В общем, есть по крайней мере три способа сделать комбинацию find
+ grep
:
grep
шаблон`find
каталогнайти -спецификаторы-print`
find
каталогнайти -спецификаторы-exec grep
шаблон{} \;
find
каталогнайти -спецификаторы-print | xargs grep
шаблонИ, конечно, здесь grep
нет ничего особенного; эти же три шаблона можно использовать для find
плюс любая команда.
Номер 1, в некотором смысле, самый старый и самый простой способ, поскольку обратные кавычки всегда были способом захватить вывод одной команды и использовать его в командной строке другой. (В последнее время у меня сложилось впечатление, что есть более новый башизм, который лучше, чем обратные кавычки, и который используют все крутые ребята, но я думаю, что я старый -таймер. )Недостаток варианта №1 в том, что если find
находит много файлов, может появиться ошибка "Слишком длинная командная строка".
Номер 2 — это специальная функция, встроенная в find
для выполнения комбинации find
+ команда. Пока это хорошо, но у него есть два недостатка:(1 )он повторно -вызывает вспомогательную команду(grep
или что-то еще )для каждого найденного файла, поэтому он может быть медленным, и (2 )если вспомогательной командой является grep
, поскольку каждый вызов grep
видит одно имя файла, он не будет отображать имена файлов в совпадении, хотя вы можете обойти это, выполнив шаблон-exec grep
{} /dev/null \;
или, в наши дни, шаблон-exec grep -H
{} \;
.
И еще есть номер 3. Насколько я знаю, xargs
был изобретен, чтобы обойти ограничения первых двух. Хотя xargs
теоретически является программой общего назначения -, я подозреваю, что на практике она почти никогда не используется с какой-либо парой программ, кроме find
и grep
. Он полностью устраняет недостаток #1; он будет работать с произвольным количеством найденных файлов. Это эффективно, хотя, если вам не повезет, он будет иногда вызывать grep
одно последнее имя файла, а это означает, что вы все равно захотите использовать трюк /dev/null
или -H
. И у него есть свой недостаток :— он не работает, если какое-либо из найденных имен файлов содержит пробелы. Но и это можно обойти:
find
каталогнайти -спецификаторы-print0 | xargs -0 grep
шаблон
(Я бы очень хотел, чтобы xargs
был написан так, чтобы по умолчанию принимать имена файлов, разделенные новой строкой -, вместо пробелов, но это разглагольствования для другого дня.)
В bash достаточно одного набора двойных -кавычек вокруг всего этого:
$ cat script
echo "my_cmd --attr1 $(($1-$2)) --attr2 $(($1-$2+$3)) --attr3 $(($2+1))"
$./script 20 10 10
my_cmd --attr1 10 --attr2 20 --attr3 11
Двойные кавычки разрешают замену на $
, одинарные -кавычки рассматривают их как литералы.