Как использовать канал в параметре exec для команды поиска? - PullRequest
71 голосов
/ 15 сентября 2008

Я пытаюсь создать команду поиска для обработки группы файлов в каталоге с использованием двух разных исполняемых файлов. К сожалению, -exec on find не позволяет использовать pipe или даже \|, потому что оболочка сначала интерпретирует этот символ.

Вот что конкретно я пытаюсь сделать (что не работает, потому что канал завершает команду поиска):

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print

Ответы [ 6 ]

77 голосов
/ 15 сентября 2008

Попробуйте это

find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print

В качестве альтернативы вы можете попытаться встроить выражение exec в скрипт sh, а затем выполнить:

find -exec some_script {} \;
11 голосов
/ 15 сентября 2008

Немного другой подход будет использовать xargs:

find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123

, который я всегда находил немного проще для понимания и адаптации (аргументы -print0 и -0 необходимы для работы с именами файлов, содержащими пробелы)

Этот может (не проверен) более эффективен, чем использование -exec, поскольку он перенаправляет список файлов в xargs, а xargs гарантирует, что командная строка jhead не будет слишком длинной.

3 голосов
/ 27 февраля 2011

Использование команды find для этого типа задачи, возможно, не лучшая альтернатива. Я часто использую следующую команду для поиска файлов, которые содержат запрашиваемую информацию:

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
3 голосов
/ 15 сентября 2008

С -exec вы можете запустить только один исполняемый файл с некоторыми аргументами, а не произвольными командами оболочки. Чтобы обойти это, вы можете использовать sh -c '<shell command>'.

Обратите внимание, что использование -exec довольно неэффективно. Для каждого найденного файла команда должна быть выполнена снова. Было бы более эффективно, если бы вы могли избежать этого. (Например, перемещая grep за пределы -exec или передавая результаты от find до xargs, как предлагает Palmin .)

1 голос
/ 15 сентября 2008

Поскольку это выводит список, вы бы не:

find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123

или

find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123

Поместите ваш grep в результаты поиска -exec.

0 голосов
/ 01 февраля 2018

Есть еще один способ сделать это, но это тоже довольно гетто.

Используя параметр оболочки extquote, вы можете сделать что-то похожее на это, чтобы найти вещи exec и затем направить их в sh.

root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

Я просто решил, что добавлю это, потому что, по крайней мере, так, как я это представлял, это было ближе к первоначальному вопросу OP об использовании каналов в exec.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...