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

StackOverflow https://stackoverflow.com/questions/62044

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
Это было полезно?

Решение

Попробуй это

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

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

find -exec some_script {} \;

Другие советы

Несколько иным подходом было бы использование xargs:

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

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

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

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

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

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

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

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

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

или

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

Поместите свой grep в результаты find -exec.

Есть какой-то другой способ, которым вы можете это сделать, но это тоже довольно гетто.

Используя опцию командной строки extquote, вы можете сделать что-то похожее на это, чтобы заставить find 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top