it-swarm-ru.tech

Как использовать канал в параметре exec для команды поиска?

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

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

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

Попробуй это

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

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

find -exec some_script {} \;
78
Martin Marconcini

Несколько иной подход - использовать xargs:

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

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

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

12
Palmin

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

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

3
mweerden

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

for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
3
Dimitar

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

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.

1
Xetius

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

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

[email protected] findtest # find -type f -exec echo ls $"|" cat \;|sh
filename


[email protected] findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h

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

0
linuxgeek