Есть ли способ логически объединить две команды оболочки, которые вызываются с помощью find - exec ?
Например, чтобы распечатать все файлы .csv, которые содержат строку foo вместе с ее появлением, я бы хотел сделать:
find . -iname \*.csv -exec grep foo {} && echo {} \;
но bash жалуется на «отсутствующий аргумент для« -exec »»
-exec
в последовательности или использовать один-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;
.sh
(в данном случае{}
) будет$1
и$0
будет чем-то вродеsh
. Но на самом деле, вы правы, первый аргумент проявляется как$0
. Наличие в качестве первого аргумента имени вызывающей команды - это просто соглашение, которое в этих случаях не применяется автоматически.Ответы:
-exec
является предикатом, который запускает команду (не оболочку) и оценивает ее как true или false на основе результата команды (нулевое или ненулевое состояние выхода).Так:
будет печатать путь к файлу , если
grep
находки Foo в файле. Вместо этого-print
вы можете использовать другой-exec
предикат или любой другой предикатСмотрите также операторы
!
и-o
найдите операторы отрицания и или .Кроме того, вы можете запустить оболочку как:
Или чтобы избежать запуска оболочки для каждого файла:
источник
Проблема, с которой вы сталкиваетесь, заключается в том, что оболочка сначала анализирует командную строку и видит две простые команды, разделенные
&&
оператором:,find . -iname \*.csv -exec grep foo {}
иecho {} \;
. Цитирование&&
(find . -iname \*.csv -exec grep foo {} '&&' echo {} \;
) обходит, но теперь команда выполняетсяfind
что - то вродеgrep
с аргументамиfoo
,wibble.csv
,&&
,echo
иwibble.csv
. Вам нужно дать командуfind
запустить оболочку, которая будет интерпретировать&&
оператор:Обратите внимание , что первый аргумент после
sh -c SOMECOMMAND
это$0
не$1
.Вы можете сохранить время запуска процесса оболочки для каждого файла, сгруппировав вызовы команд с помощью
-exec … +
. Для простоты обработки передайте какое-нибудь фиктивное значение,$0
чтобы"$@"
перечислить имена файлов.Если команда оболочки состоит только из двух программ, разделенных
&&
,find
может выполнить задание самостоятельно: записать два последовательных-exec
действия, а второе будет выполнено только в том случае, если первая выйдет со статусом 0.(Я предполагаю, что
grep
иecho
предназначен только для иллюстрации, так как-exec echo
может быть заменен ,-print
и полученный выход не особенно полезно в любом случае.)источник
./some-file: grep: command not found
сообщение об ошибке.-exec find sh -c '... "$1"' sh {} \;
не было бы проблемы. В вашей второй команде поиска есть опечатка (связанная).В этом конкретном случае я бы сделал:
find . -iname \*.csv -exec grep -l foo \{\} \;
Или если у вас есть подтверждение :
ack -al -G '.*\.csv' foo
Чтобы ответить на ваш актуальный вопрос, что-то вроде этого может работать:
find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;
источник