выполнить команду из find, вызванной find

Есть ли способ вызвать поиск рекурсивно?

Я хотел бы искать файлы, соответствующие данному шаблону, только в каталогах, соответствующих другому шаблону.

В основном:

for each (sub)directory D matching "*.data" do for each file F in directory D (with subdirs) matching "*.important.txt" do run command foo on F done done 

Теперь, если я откажусь от самого внутреннего требования ( выполните команду foo в F ), это довольно просто:

 find . -type d -name "*.data" \ -exec find \{\} -type f -name "*.important.txt" \; 

Однако я не нашел способ передать команду во внутреннюю find . Например, следующие распечатки находят: отсутствующий аргумент `-exec ' каждый раз, когда вызывается внутренняя находка:

  find . -type d -name "*.data" \ -exec find \{\} -type f -name "*.important.txt" \ -exec "foo \{\} \;" \; 

Любое решение должно соответствовать posix (выполняется в сценарии /bin/sh ), особенно. Я не ищу решения, которые

  • оберните внутреннюю находку в отдельный shell-скрипт
  • оберните внутреннюю находку в функцию bash

2 Solutions collect form web for “выполнить команду из find, вызванной find”

Чтобы запустить find по собственному результату, вы можете использовать аргумент -c для sh (или bash ), чтобы внешняя команда find не обрабатывала внутреннюю {} специально. Однако тогда вам нужно передать результат из внешней находки в качестве аргумента sh , который можно развернуть с помощью $0 :

 find . -type d -name "*.data" \ -exec sh -c 'find "$0" -type f -name "*.important.txt" -exec echo \{\} \;' \{\} \; 

Примечание: $0 следует указывать ( "$0" ), чтобы предотвратить проблемы с именами каталогов, содержащими пробельные символы.

На самом деле это не «рекурсивное» решение, потому что оно не позволяет произвольно глубокое вложение без какого-либо волосатого экранирования, но оно поддерживает два уровня find -exec вы просили в своем примере.

Если ваш пример похож на вашу реальную проблему, вы можете также поэкспериментировать с аргументом -path чтобы найти вместо этого:

 find . -path '*.data/*important.txt' 

версия bash (не совместимая с POSIX)

 #!/bin/bash find . -type d -name 'a *' -print0 \ | while IFS= read -r -d '' dir ; do find "$dir" -type f -name "*.c" -exec echo \{\} \; done 

Проблемы:

  • read не имеет параметра -d в POSIX
  • find не имеет параметра -print0 в POSIX

(плохой) sh (совместимый с POSIX)

 #!/bin/sh # WARNING: while this will work on directory names with spaces, # it will break on directory names that contain newlines find . -type d -name 'a *' -print \ | while IFS= read -r dir ; do find "$dir" -type f -name "*.c" -exec echo \{\} \; done 

Проблема. Как указано в комментарии, он разбивает имена каталогов, содержащие новые строки. Вы можете подумать, что это нереальная проблема, но это добавляет ненужной хрупкости вашему сценарию. Возможно, в другой программе есть ошибка, которая создаст такой каталог и т. Д.


(лучше) sh версия

см . ответ Яна Робертсона


Btw. если вам нужны ваши скрипты, совместимые с POSIX, рекомендуется использовать shellcheck . Например, заметим, что read -d не определено в POSIX.

  • Как я могу заменить эту команду оболочки?
  • find и md5sum не дают никакого выхода (find -o limit?)
  • Удалить рекурсивные файлы, которые НЕ соответствуют регулярному выражению
  • Найти файл, имя которого содержит заданные подстроки одновременно
  • Перемещение или копирование файлов определенного типа из подкаталогов с таким же именем
  • Найти команду - список аргументов слишком длинный
  • Создание задачи Cron для уничтожения остановленных / неудачных прогонов в системе
  • Скопируйте файл и структуру файла и объедините в новый каталог
  • поиск и подглаживание (и подстановочные знаки)
  • Использовать для цикла в find exec
  • Рекурсивно перечислить все каталоги, содержащие один или несколько файлов изображений jpg
  • Interesting Posts

    Мониторинг файлов непрерывно с помощью lsof

    Избегайте пакетов -dbg_version на сервере apt-cacher-ng

    как написать регулярное выражение, используя grep, чтобы найти строки, начинающиеся с «O» или «o», и содержат 2 последовательных фрагментатора

    Джесси, чтобы продлить обновление; прокси-сервер squid сломан

    Можно загрузить все пакеты из «groupinstall», а затем запустить (yum –nogpgcheck localinstall *. Rpm)?

    Grep строка с пробелами из файла

    Я изменил / etc / sudoers, и теперь я не могу работать как sudo

    Как переключить пользователя и передать пароль в скрипте Groovy?

    Что означает Unix-программирование?

    Скрипт Socat exec в туннеле

    Скопировать файлы без шифрования (ssh) в локальной сети

    Установка программы в качестве обоев

    Почему grep показывает разные результаты, когда я использую file1 как шаблон в файле2 и наоборот?

    Каков интерфейс моего hdd?

    Как вызвать скрипт оболочки из кода Javascript?

    Linux и Unix - лучшая ОС в мире.