2016-05-25 2 views
1

Я хотел бы найти в некоторых dir и сделать awk по файлам в этом указателе, а затем заменить исходные файлы на каждый результат.Можете найти в файле имена файлов найденных файлов?

find dir | xargs cat | awk ... | mv ... > filename 

Так что мне нужно имя файл (каждый из файлов найденных находки) в последней команде. Как я могу это сделать?

+0

Какая у вас проблема? –

+1

напишите сценарий и передайте имя файла 'find dir -exec myscript {} \;' где myscript начинается с типа 'name = '$ 1" 'и делает cat, awk и т. Д. –

+0

' xargs cat' здесь бессмыслен (и не будет работать, потому что он будет комбинировать файлы). 'xargs awk' будет лучше (и позволит' awk' обрабатывать каждый файл независимо, включая запуск 'mv', если вы действительно этого хотите. –

ответ

0

Я хотел бы использовать цикл, как:

for filename in `find . -name "*test_file*" -print0 | xargs -0` 
do 
    # some processing, then 
    echo "what you like" > "$filename" 
done 

EDIT: как отмечено в комментариях, преимущества -print0 | xargs -0 теряются из-за петли for. И имена файлов, содержащие пробел, все еще не обрабатываются правильно.

Следующая while цикл не будет обрабатывать необычные имена файлов ни (хорошо знать его, хотя он не был в этом вопросе), но имена файлов со стандартным белым пространством, по крайней мере, так она работает лучше, в самом деле:

find . -name "*test*file*" -print > files_list 

while IFS= read -r filename 
do 
    # some process 
    echo "what you like" > "$filename" 
done < files_list 
+0

Я знаю, но мне было интересно, можете ли вы это сделать, ставя себя в дело с 'find dir', а не с' for f in $ (find dir) ' – ericj

+0

Возможно, вы можете добавить эту точность в свой вопрос? Не сохраняя имена файлов где-то, я не знаю, как вы можете вернуть их после нескольких команд. – zezollo

+0

'найти каталог | в то время как read filename' будет вести себя очень похоже и * делает * начинать с поиска dir, но zezollos отвечает на случаи, например. с новыми символами в именах файлов, которые не будут обрабатываться этим, но никто не понимает, почему вы хотите «начать с' find dir' » –

0

Вы можете сделать что-то подобное (но я бы не рекомендовал его вообще).

find dir -print0 | 
    xargs -0 -n 2 awk -v OFS='\0' '<process the input and write to temporary file> 
     END {print "temporaryfile", FILENAME}' | 
    xargs -0 -n 2 mv 

Это передает файлы awk непосредственно два одновременно (что исключает проблему с оригиналом где cat получите сотни (возможно, более) файлы в качестве аргументов все сразу и плюнуть все их содержания в awk через стандартный ввод одновременно и, таким образом, полностью теряют свое индивидуальное содержимое и имена файлов).

Затем он имеет awk написать обработанный вывод во временный файл, а затем выводит имя временного файла и исходное имя файла, где xargs забирает их (опять два одновременно) и работает mv на пары временного файла/исходный файл имена.

Как я уже сказал в начале, это ужасный способ сделать это.

Если у вас есть достаточно новую версию GNU awk (версии 4.1.0 или более поздней версии), то вы можете просто использовать аргумент -i (на месте), чтобы awk и использовать (я считаю):

find dir | xargs awk -i '......' 

Без этого я бы использовал цикл while формы в Bash FAQ 001, чтобы читать вывод find по очереди и работать с ним в цикле.