Как использовать> в команде xargs?
Я хочу найти команду bash, которая позволит мне grep каждый файл в каталоге и записать вывод этого grep в отдельный файл. Я думаю, было бы сделать что-то вроде этого
ls -1 | xargs -I{} "grep ABC '{}' > '{}'.out"
но, насколько я знаю, xargs не любит двойные кавычки. Однако если я удалю двойные кавычки, то команда перенаправит вывод всей команды в один файл с именем" {}".выход вместо серии отдельных файлов.
кто-нибудь знает как это сделать с помощью xargs? Я просто использовал этот сценарий grep в качестве примера, чтобы проиллюстрировать мою проблему с xargs, поэтому любые решения, которые не используют xargs, не применимы для меня.
3 ответов:
не делайте ошибку, делая это:
sh -c "grep ABC {} > {}.out"это сломается при многих условиях, в том числе фанки имена файлов и невозможно процитировать правильно. Ваш
{}всегда должен быть один совершенно отдельный аргумент для команды, чтобы избежать ошибок ввода кода. Что вам нужно сделать, это:xargs -I{} sh -c 'grep ABC "" > ".out"' -- {}относится к
xargsа такжеfind.кстати, никогда не используйте xargs без
-0вариант (если только для очень редких и контролируемое одноразовое интерактивное использование, когда вы не беспокоитесь об уничтожении своих данных).также не разбирать
ls. Когда-либо. Использовать подстановку илиfindвместо этого: http://mywiki.wooledge.org/ParsingLsиспользовать
findдля всего, что требует рекурсии и простой цикл с глобусом для всего остального:find /foo -exec sh -c 'grep "" > ".out"' -- {} \;или нерекурсивных:
for file in *; do grep "$file" > "$file.out"; doneобратите внимание на правильное использование цитат.
решение без
xargsследующий:find . -mindepth 1 -maxdepth 1 -type f -exec sh -c "grep ABC '{}' > '{}.out'" \;...и то же самое можно сделать С
xargsполучается:ls -1 | xargs -I {} sh -c "grep ABC '{}' > '{}.out'"
Edit: одинарные кавычки добавлены после замечания lhunath.
Я предполагаю, что ваш пример-это просто пример, и что вам может понадобиться > для других вещей. GNU Parallel http://www.gnu.org/software/parallel/ может быть ваше спасение. Он не нуждается в дополнительном цитировании до тех пор, пока ваши имена файлов не содержат \n:
ls | parallel "grep ABC {} > {}.out"если у вас есть имена файлов с \n в нем:
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
Comments