выполнить команду из 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.

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

    Linux Mint на ноутбуке выходит из строя, дает ошибку grub

    MailScanners: spamassassin vs spamd & clamav vs clamd

    Переменная среды LD_LIBRARY_PATH

    Интерфейс и псевдоним одновременно

    Может ли пропускать «fsck» при загрузке через последовательный порт?

    Здание zsh без администратора: нет библиотеки обработки терминала

    Блокировка телеграммы с помощью / etc / hosts

    Вырезано ядро ​​для ноутбука

    Реализация расширенного регулярного выражения для добавления переменной числа ведущих нулей на основе позиции в строке

    BASH: использование awk для фильтрации уникальных строк приводит к 0 массиву длины

    Могу ли я автоматизировать многотомную функцию tar?

    Хранение точечных файлов в синхронизации для разных папок

    Как отключить «apt-daily.service» на изображении виртуальной виртуальной машины Ubuntu?

    Планируется ли ввод / вывод dm-multipath?

    Как обеспечить, чтобы пользователи не могли войти в систему, кроме FTP?

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