Вопрос или проблема
Я хочу перечислить все директории в текущей директории и передать эти директории в качестве аргумента другой команде find. Пример ниже объясняет это правильно.
$ find . -maxdepth 1 -type d
.
./dir1
./dir2
./dir3
./dir4
$ echo -e "\n" ; find (вышеуказанные директории как аргумент) -exec md5sum {} +
Таким образом, я получаю контрольные суммы для всех файлов в папке по отдельности, разделенные пробелом. Я думаю, что вышеуказанный пример правильно объясняет проблему. Извините за мой плохой английский, у меня очень мало знаний о командах Linux, пожалуйста, простите меня. Спасибо заранее.
Вы можете сделать следующее:
find . ! -name . -prune -type d -exec sh -c '
for dir do
printf "\n\n"
find "$dir" -type f -exec md5sum {} +
done' sh {} +
(здесь мы экранируем }
внутри встроенного кода sh
с помощью \
, чтобы {}
не появлялся там, потому что в некоторых реализациях find
внешний find
заменит его на путь директории, даже если {}
не является аргументом).
Я также заменил нестандартный -maxdepth 1
на стандартный ! -name . -prune
, который здесь больше похож на -mindepth 1 -maxdepth 1
, так как он пропускает .
(на глубине 0), что, как я подозреваю, здесь вам и нужно.
Если вы используете zsh
, вы можете сделать это без необходимости в find
и с отсортированным списком директорий и файлов:
for dir in *(ND/); do
print '\n'
files=( $dir/**/*(ND.) )
(( $#files )) && md5sum -- $files
done
Вы также можете пропустить печать разделителя при первом запуске и для директорий без обычных файлов:
run=0
for dir in *(NDF); do
files=( $dir/**/*(ND.) )
if (( $#files )); then
(( run++ )) && print '\n'
md5sum -- $files
fi
done
Будьте осторожны на системах, где есть ограничение на размер списка аргументов, которые могут быть переданы команде при выполнении (большинство из них), выполнение md5sum
может не удаться, если в (и ниже) одной директории много обычных файлов. Вам может потребоваться использовать zargs
, чтобы обойти это ограничение. find
‘s -exec cmd {} +
автоматически разбивает этот список.
Ответ или решение
Да, вы можете передать список директорий, найденный с помощью команды find
, в другую команду find
, чтобы выполнить md5sum
для файлов в каждой директории. Приведу пример того, как это можно сделать.
Пример использования find
с md5sum
Допустим, вы хотите получить контрольные суммы.md5 для всех файлов в директориях в текущем каталоге. Вы можете использовать следующую команду:
find . ! -name . -prune -type d -exec sh -c '
for dir do
printf "\n\n"
find "$dir" -type f -exec md5sum {} +
done' sh {} +
Объяснение команды:
-
find . ! -name . -prune -type d
: Эта часть находит все директории в текущем каталоге, при этом пропуская саму директорию.
.! -name .
избегает обработки текущей директории.-prune
предотвращает рекурсивный поиск в найденных директориях.-type d
указывает, что нужно искать только директории.
-
-exec sh -c '...' sh {} +
: Эта конструкция запускает командную оболочкуsh
, передавая ей найденные директории как аргументы.- Внутри оболочки идет цикл
for dir do ... done
, который проходит по всем найденным директориям. printf "\n\n"
выводит два перехода на новую строку для удобства отображения.
- Внутри оболочки идет цикл
-
find "$dir" -type f -exec md5sum {} +
: Внутри цикла мы вызываемfind
снова для каждой директории, чтобы найти все файлы (-type f) и вычислить их контрольные суммы с помощьюmd5sum
.
Важно:
- Обязательно экранируйте фигурную скобку
{}
внутри телаsh -c
, чтобы избежать неправильной подстановки имени файла. Убедитесь, что она экранирована, иначеfind
может подставить путь к директории вместо ожидаемого аргумента. - Если в директориях достаточно много файлов, может возникнуть ошибка, если количество аргументов превышает лимит операционной системы. В этом случае имеет смысл использовать
find
с-exec ... +
, который автоматически обрабатывает это разделение аргументов.
Альтернативный способ с помощью zsh
:
Если вы используете zsh
, то можно выполнить аналогичную задачу без использования find
:
run=0
for dir in *(NDF); do
files=( $dir/**/*(ND.) )
if (( $#files )); then
(( run++ )) && print '\n'
md5sum -- $files
fi
done
Объяснение для zsh
версии:
*(NDF)
— это расширение, которое ищет все директории, игнорируя пустые.files=( $dir/**/*(ND.) )
находит все файлы в текущей директории и поддиректориях, включая скрытые.- Проверяет, есть ли найденные файлы с помощью
if (( $#files ))
. Если есть, то выводит переход на новую строку и вычисляет контрольные суммы с помощьюmd5sum
.
Эти методы позволяют эффективно получить контрольные суммы файлов в директориях. Если у вас есть дополнительные вопросы или нужны уточнения, пожалуйста, дайте знать!