LINUX.ORG.RU

Вопрос по циклам 2

 , , ,


0

2

1. Есть директория с текстовым файлом, где каждая строчка с новой строки

2. Есть директория с файлами.

3. Нужно строки применить к файлам, по типу «chgrp строка1 файл1, chgrp строка2 файл2»

Пробывал следующий цикл, но работает максимально криво, результат - строки не соответствуют нужным файлам. Есть другие идеи ? Либо есть какие-то ошибки ?

#!/bin/sh

cd /home/man/httpd-logs # перехожу в директорию с файлами
datax="/home/man/data.txt" #строки

target=$(ls -ll | awk '{print $9}' | grep 'access.log') #команда выводит нужные мне файлы в директори, не обращайте на неё внимания. считайте, что это просто вывод файлов в директории.

for i in $target
do 
read line
chgrp $line $i
done < $datax

import itertools, os

print(list(zip(itertools.repeat('chgrp'), (s.strip() for s in open('data.txt', 'r').readlines()), (os.path.join('files', file) for file in os.listdir('files')))))

aedeph_ ★★ ()
Ответ на: комментарий от aedeph_

на место files - путь к директории ? и на место data.txt - путь к этому файлу ?

не работает

gamble ()
Ответ на: комментарий от InterVi

Ок,

python -c "print(list(zip(__import__('itertools').repeat('chgrp'), (s.strip() for s in open('data.txt', 'r').readlines()), (__import__('os').path.join('files', file) for file in sorted(__import__('os').listdir('files'))))))"
aedeph_ ★★ ()
Последнее исправление: aedeph_ (всего исправлений: 3)
Ответ на: комментарий от aedeph_

с питоном никак, есть ньюансы.

жду ещё вариантов на баше от остальных. или прощай работа.

gamble ()

Ничё не понял, но я вижу это так:

#!/bin/bash
logs="/home/man/httpd-logs"
datax="/home/man/data.txt"
target=$(ls "$logs" | grep 'access.log' )
while read line
do
for i in $target
do
read line
chgrp $line $i
done
done < $datax

Pyzia ★★★★★ ()
Ответ на: комментарий от unterwulf

почему именно ls *access.log ?

нужные файлы должны выводиться по команде ls -ll | awk '{print $9}' | grep 'access.log'

и к ним применяться chgrp где каждая группа берётся из текстового файла

gamble ()

Тебе уже несколько раз в этом и предыдущем тредах говорили, что если в файле группы идут без имён файлов, то благодати не будет. И вообще мы здесь явно имеем дело с ярко выраженной XY problem. Объясни толком, почему такая наркоманская вводная.

legolegs ★★★★★ ()

я бы сделал так:

#!/bin/bash
count=1

for file in `find /home/man/httpd-logs/ -type f | grep 'access.log'`
do
    chgrp `sed -n ${count}p /home/man/data.txt` ${file}
    count=`$count+1`
done 
Crystal_HMR ★★★ ()
Ответ на: комментарий от gamble

Как именно не фурычит? Сдвиг на один файл присутствует, так это можно каким-нить костылём пофиксить и вообще, unterwulf предложил супер-решение, что у него не так?

Pyzia ★★★★★ ()

Есть папка
Есть директория

У тебя конфликт стандартов. Конечно же ничего работать не будет.

MimisGotAPlan ()
Ответ на: комментарий от Crystal_HMR

count=`$count+1`

Какой интересный у вас bash. Если уж извращаться, то ... sed -n $((count++))p ...

Но это действительно извращение, ибо каждый раз запускать sed для последовательного получения строчек из файла полный ужас.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)

Забери уже у папки текстовой файл. Хватит его мучить :)

peregrine ★★★★★ ()
Ответ на: комментарий от legolegs

Да ему уже три метода подсказали

Да я в курсе, предыдущий топик моим сообщением и закончился.

но он не рассказывает, что ему надо и что не получается.

Ну вы же в курсе, что и не получится, при такой то задаче.

vodz ★★★★★ ()
Ответ на: комментарий от legolegs

Код Crystal_HMR - после запуска, не единого сообщения о чём-либо, и сам результат не поменялся.

у Pyzia - выбрасывает usage: chgrp [-fhvx] [-R [-H | -L | -P]] group file ...

код unterwulf - paste $datax <(ls *access.log) | xargs -n 2 chgrp

выбрасывает Syntax error: "(" unexpected

остальные варианты с циклами выбрасывают ошибки по типу - usage chgrp: not found файл

gamble ()
Ответ на: комментарий от legolegs

имена групп для файлов, для которых и применяется chgrp имягруппы файл. примерно так:

  • hord
  • torb
  • jord

и т.д

gamble ()
Ответ на: комментарий от legolegs

только без точек в начале и без пробелов, на форуме не получается по другому показать, что они все с новой строки.

gamble ()
Ответ на: комментарий от gamble

Да причём тут awk? Какой код вы бы не применили (а в начале этого второго топика он на первый взгляд рабочий), у вас всегда будут глюки, ибо информации для соответствия файлов и групп скрипту вы и не даёте, но что-то от него хотите.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Но это действительно извращение, ибо каждый раз запускать sed для последовательного получения строчек из файла полный ужас.

а какой другой вариант при такой задаче? Ну давайте в пямять загрузим весь файл в виде массива с разделителем newline, и будем выцеплять элементы массива. Есть сотни вариантов сделать то, что нужно.

Кстати подозреваю, что не работает потому, что я повелся на ваше grep access.log. Там не надо. Ну и второе - слегка в языках запутался, но надеялся что тс поймет и прочтет про инкремент

Вот вариант 2, думаю что access.log это таки файл, который надо читать:

#!/bin/bash
count=1
cd /home/man/httpd-logs 

for file in `ls -ll | awk '{print $9}' | grep 'access.log'` #хотя я бы использовал find
#или ls -1. Нет смысла получать список фалов по ls -l
#а потом авкашить только его название. Глупая работа
do
    chgrp `sed -n ${count}p /home/man/data.txt` ${file}
    count=$((count+1))
done 

PS. Следующее «не работает» с выводом

bash -x /path/to/script.sh

Crystal_HMR ★★★ ()
Последнее исправление: Crystal_HMR (всего исправлений: 2)
Ответ на: комментарий от vodz

если я назначу любое название группы для файла в ручную - оно назначится без проблем.

но через скрипт сделать это правильно не получается, первая строка соотстветсвует первому файлу, вторая второму, третья третьему и т.д.

и мне это нужно сделать через сценарий. и оно просто не работает.

в ручную это получилось бы без проблем, но файлов 1500 штук

gamble ()
Ответ на: комментарий от Crystal_HMR

а какой другой вариант при такой задаче?

Вы не поверите, но у ТСа этот момент с самого начала ещё с прошлого топика оптимален: while true; do read l; done < file

Кстати подозреваю, что не работает потому, что я повелся на ваше grep access.log.

МОЁ?!

vodz ★★★★★ ()
Ответ на: комментарий от Crystal_HMR

sed: /home/sevenx/out.txt: No such file or directory usage: chgrp [-fhvx] [-R [-H | -L | -P]] group file ...

gamble ()
Ответ на: комментарий от gamble

В POSIX нет понятий «первый файл», «второй файл» и т.д. find перечисляет файлы как попало, ls тоже не обязан их сортировать (GNU ls сортирует, но у тебя ведь BSD). И уж конечно нельзя исключать, что количество записей в data.txt не соответствует числу пар файлов. Если б соответствовало код из стартового поста работал бы.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от gamble

первая строка соотстветсвует первому файлу

какому первому файлу? Если б оно соответсвовало, то ваш код и отработал бы без глюков. Конечно, тут намекнули, что это может быть ещё от других каталогов в вашем рабочем каталоге. Но это то вы способны сами определить?

Неужели трудно дописать echo к chgrp, посмотреть что оно пытается сделать и сравнить с тем, что вы бы руками делали? Вы никогда ничего не отлаживали?

vodz ★★★★★ ()
Ответ на: комментарий от Crystal_HMR

да не ТВОЁ, а тс'а. Чеж ты занудный то такой?

Нахрен мне чужие глюки? А во то, что ТС не читает, что не ему писано, мы — видим.

vodz ★★★★★ ()
Ответ на: комментарий от legolegs

я сортирую файлы через ls -ll | awk '{print $9}' | grep 'access.log

количество записей уже соответсвует файлам, потому что я исключил пары, оставил только access.log файлы, без других файлов error.log.

gamble ()
Ответ на: комментарий от vodz

Есть полу-кривой вариант, который я умалчивал, потому что оно не правильно присваивает группы файлам. Я ждал других вариантов, но остальные у меня вообще не работает

for i in $отсортированная_директория do read line echo chgrp $line $i done < $текстовыйфайл

gamble ()
Ответ на: комментарий от gamble

Во-первых, достаточно ls | grep access.log.

Во-вторых, стоит лишь сделать тестовый прогон вот так

target=$(ls | grep 'access.log')

for i in $target
do 
read line
echo chgrp $line $i
done < $datax > report.txt
чтобы найти свою ошибку.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от vodz

Спасибо за поправку. А про for i in * и сортировку стандарт что-нибудь говорит?

legolegs ★★★★★ ()
Ответ на: комментарий от gamble

А неверно сначала или с середины? А как ты определяешь, верно или нет? А ты можешь соответствие файл->группа брать из этого проверочного источника?

legolegs ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.