У меня есть следующая структура файла / каталога:

tsunami # find .
.
./dir1
./dir1/dirinner
./dir1/dirinner/innerfile
./logs
./messages

Я пытаюсь рекурсивно найти файлы и обработать их, используя find/exec.

Версия find (поставляется с busybox) не позволяет использовать обнаруженное имя файла более одного раза в команде exec, как описано здесь. Итак, я использовал одно из предложенных решений. Итак, я переписал это:

find  * -type f -exec echo {}  +

к этому:

find  * -type f -exec sh -c 'echo $0' {}  +

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

Вот вывод для обоих:

tsunami # find  * -type f -exec echo {}  +
dir1/dirinner/innerfile logs messages
tsunami # find  * -type f -exec sh -c 'echo $0' {}  +
dir1/dirinner/innerfile

Как это исправить? Мне нужно, чтобы найти все файлы, а не только самый внутренний.

1 ответ1

2

Я предполагаю, что echo - это просто ваша морская свинка, на которой можно проводить эксперименты (единственная find . -type f выполняет печать путей к файлам).

В моем ответе я использую find . … вместо find * … - для простоты. Если у вас есть причины для использования оболочки, то продолжайте.

Ваша проблема в том, что -exec … {} + синтаксис заменяет множество путей одновременно вместо {} ; поэтому в -exec sh -c 'echo $0' {} + sh получает много аргументов, но $0 относится только к одному, остальные остаются неиспользованными.

Используйте "$@" , это означает "$1" "$2" "$3" … . Поскольку он пропускает $0 вам нужно указать дополнительный (фиктивный) аргумент. Для sh я использую sh:

find . -type f -exec sh -c 'echo "$@"' sh {} +

Также обратите внимание, что если будет найдено слишком много файлов для обработки одной командной строкой, будет запущено несколько sh s (следовательно, несколько echo -s).


В качестве альтернативы вместо -exec … {} + используйте -exec … \;:

find . -type f -exec sh -c 'echo "$0"' {} \;

Это будет запускать отдельную sh для каждого файла, поэтому достаточно $0 .

Другое отличие: большинство реализаций find требуют, чтобы {} находилось непосредственно перед + , но в случае \; это {} может быть где-то между -exec и \; , Это означает, что:

  • -exec foo {} bar + неверен;
  • -exec foo {} bar \; все в порядке.

Эта разница не имеет значения в вашем конкретном случае, хотя.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .