2009-05-10 2 views
120

Я хочу найти команду bash, которая позволит мне grep каждый файл в каталоге и записать вывод этого grep в отдельный файл. Мое предположение было бы сделать что-то вроде этогоКак использовать> в команде xargs?

ls -1 | xargs -I{} "grep ABC '{}' > '{}'.out" 

, но, насколько я знаю, xargs не любит двойные кавычки. Однако, если я удаляю двойные кавычки, команда перенаправляет вывод всей команды в один файл с именем «{}». Out вместо нескольких отдельных файлов.

Кто-нибудь знает, как это сделать, используя xargs? Я просто использовал этот сценарий grep в качестве примера, чтобы проиллюстрировать мою проблему с xargs, поэтому любые решения, которые не используют xargs, не применимы для меня.

ответ

146

Не делайте ошибку, делая это:

sh -c "grep ABC {} > {}.out" 

Это сломается под большим условия, в том числе фанки имен файлов и невозможно процитировать правильно. Ваш {} должен всегда быть единственным отдельным аргументом команды, чтобы избежать ошибок при вводе кода. Что вам нужно сделать, это:

xargs -I{} sh -c 'grep ABC "$1" > "$1.out"' -- {} 

Относится к xargs, а также find.

Кстати, никогда не используйте xargs без опции -0 (если только для очень редкого и контролируемого одноразового интерактивного использования, где вас не беспокоят об уничтожении ваших данных).

Также не разбирайте ls. Когда-либо. Используйте подстановку или find вместо: http://mywiki.wooledge.org/ParsingLs

Используйте find для всего, что нуждается в рекурсии и простой цикл с Glob для всего остального:

find /foo -exec sh -c 'grep "$1" > "$1.out"' -- {} \; 

или нерекурсивна:

for file in *; do grep "$file" > "$file.out"; done 

Примечание правильное использование котировок.

+1

+1. В самом деле, я не должен был забывать о котировках. – Stephan202

+0

Приобретено, но сомнение. не используя 'xargs' без' -0': это применимо только при выводе 'find' с помощью' xargs', правильно? когда я делаю 'xargs -a ' как я буду использовать это? Большинство команд, таких как 'grep' выходы с' \ n', а не '\ 0.' Единственный способ, с которым я могу работать, это снова использовать' tr', чтобы исправить это. Но почему это важно использовать только с '-0'? – legends2k

+2

@ legends2k, потому что, когда вы не используете '-0',' xargs' возьмет ваши имена файлов и сломает все пробелы, кавычки и обратные слэши в них. Вы должны просто забыть о 'xargs' как инструменте. Если у вас есть строки, используйте цикл bash для итерации строк: 'while read line; do "$ REPLY"; done lhunath

34

Раствор без xargs является следующее:

find . -mindepth 1 -maxdepth 1 -type f -exec sh -c "grep ABC '{}' > '{}.out'" \; 

... и то же самое можно сделать с xargs, получается:

ls -1 | xargs -I {} sh -c "grep ABC '{}' > '{}.out'" 

Редактировать : одинарные кавычки добавляются после замечания lhunath.

+0

Он сказал, что он хочет использовать xargs. Я также разместил решение без него, но удалил, как только увидел, что ему нужны xargs. – Zifre

+0

Вы правы. Причина, по которой я опубликовал свой ответ, состояла в том, что лучше иметь альтернативное решение для выполнения работы, чем вообще. Оказывается, он поставил меня на правильный путь, чтобы найти нужный ответ (т. Е. Трюк sh-c). – Stephan202

+0

+1 Это второе решение работает, хотя я уверен, что есть лучший способ ... – Zifre

12

Я предполагаю, что ваш пример - всего лишь пример и что вам может понадобиться> для других целей. GNU Parallel http://www.gnu.org/software/parallel/ может быть вашим спасением.Он не нуждается в дополнительной процитировать до тех пор, пока ваши имена файлов не содержат \ п:

ls | parallel "grep ABC {} > {}.out" 

Если у вас есть имена файлов с \ п в нем:

find . -print0 | parallel -0 "grep ABC {} > {}.out" 

В качестве дополнительного бонуса вы получите задания выполняются в параллели.

Редактировать.

Вы можете установить GNU Parallel просто:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel 
chmod 755 parallel 

Смотрите интро видео, чтобы узнать больше: установка http://pi.dk/1

10 секунд:

wget pi.dk/3 -qO - | sh -x 
+1

Не поставляется по умолчанию, нет во многих репозиториях :( – Konrads

Смежные вопросы