Мне нужно рекурсивно перебрать каталог и удалить все файлы с расширением .pdf
и .doc
. Мне удается рекурсивно перебирать каталог, но не удается отфильтровать файлы с вышеупомянутыми расширениями файлов.
Мой код пока
#/bin/sh
SEARCH_FOLDER="/tmp/*"
for f in $SEARCH_FOLDER
do
if [ -d "$f" ]
then
for ff in $f/*
do
echo "Processing $ff"
done
else
echo "Processing file $f"
fi
done
Мне нужна помощь для завершения кода, так как я никуда не денусь.
rm
что это часть кода OP, но на самом деле это не имеет отношения к заданному вопросу. Я думаю, что было бы безопаснее, если бы ответы были сформулированы с использованием такой безобидной команды, какecho
.Ответы:
find
только для этого.источник
-delete
вариант.find ... -print0 | xargs -0 ...
, а не сырье найти | xargs, чтобы избежать проблем с именами файлов, содержащими символы новой строки.xargs
без опций - почти всегда плохой совет, и это не исключение. Используйтеfind … -exec
вместо этого.В качестве продолжения ответа mouviciel, вы также можете сделать это как цикл for вместо использования xargs. Я часто нахожу xargs громоздким, особенно если мне нужно делать что-то более сложное в каждой итерации.
Как прокомментировал ряд людей, это потерпит неудачу, если в именах файлов есть пробелы. Вы можете обойти это, временно установив IFS (внутренний разделитель полей) на символ новой строки. Это также не работает, если
\[?*
в именах файлов есть символы подстановки . Вы можете обойти это, временно отключив подстановочное расширение (globbing).Если в именах файлов есть переводы строк, это тоже не сработает. Вам лучше с решением на основе XARGS:
(Здесь необходимо использовать экранированные скобки, чтобы
-print0
применить их к обоимor
пунктам.)GNU и * BSD find также имеют
-delete
действие, которое будет выглядеть так:источник
for f in $(find ...)
. Просто не используйте этот метод.Без
find
:/tmp/*
файлы в каталоге и/tmp/**/*
файлы в подпапках. Возможно, вам нужно включить параметр globstar (shopt -s globstar
). Так что для вопроса код должен выглядеть так:Обратите внимание, что для этого требуется bash ≥4.0 (или zsh без
shopt -s globstar
, или ksh сset -o globstar
вместоshopt -s globstar
). Кроме того, в bash <4.3 это перебирает символические ссылки на каталоги, а также на каталоги, что обычно нежелательно.источник
for f in /tmp/**
будет достаточно. Включает файлы из / tmp dir.for f in /tmp/*.{pdf,doc} tmp/**/*.{,pdf,doc} ; do
**
хорошее расширение, но не переносимое в POSIXsh
. (Этот вопрос помечен как bash, но было бы неплохо отметить, что в отличие от нескольких решений здесь, это действительно только Bash. Или, ну, это работает и в некоторых других расширенных оболочках.)Если вы хотите сделать что-то рекурсивно, я предлагаю вам использовать рекурсию (да, вы можете сделать это с помощью стеков и так далее, но эй).
Тем не менее,
find
вероятно, это лучший выбор, как уже было предложено.источник
Вот пример использования shell (
bash
):источник
Это не отвечает на ваш вопрос напрямую, но вы можете решить вашу проблему с помощью одной строки:
В некоторых версиях find (GNU, BSD) есть
-delete
действие, которое вы можете использовать вместо вызоваrm
:источник
Этот метод хорошо обрабатывает пробелы.
Редактировать, исправляет по одному
источник
Для bash (начиная с версии 4.0):
Вот и все.
Конечное расширение ".ext" там для выбора файлов (или каталогов) с таким расширением.
Опция globstar активирует ** (поиск рекурсивно).
Опция nullglob удаляет *, когда не соответствует ни файлу / директории.
Опция dotglob включает в себя файлы, которые начинаются с точки (скрытые файлы).
Помните, что до bash 4.3
**/
также проходит символические ссылки на каталоги, что нежелательно.источник
Следующая функция рекурсивно выполняет итерацию по всем каталогам в
\home\ubuntu
каталоге (вся структура каталогов в Ubuntu) и применяет необходимые проверки вelse
блоке.источник
Это самый простой способ, которым я знаю, чтобы сделать это:
rm **/@(*.doc|*.pdf)
**
делает эту работу рекурсивно@(*.doc|*.pdf)
ищет файл, заканчивающийся в pdf ИЛИ docЛегко безопасно проверить путем замены
rm
сls
источник
Нет причин направлять вывод
find
в другую утилиту.find
имеет-delete
встроенный флагисточник
Другие предоставленные ответы не будут включать файлы или каталоги, которые начинаются с. у меня сработало следующее:
источник
Просто сделать
источник
Следующее будет рекурсивно перебирать данный каталог и перечислять все содержимое:
for d in /home/ubuntu/*; do echo "listing contents of dir: $d"; ls -l $d/; done
источник
ls -l /home/ubuntu/*/
бесполезно, поэтому бесполезно.Если вы можете изменить оболочку, используемую для запуска команды, вы можете использовать ZSH для выполнения этой работы.
Это будет рекурсивно перебирать все файлы / папки.
источник