Что такое команда для удаления всех файлов, но не каталогов?

23

Допустим, у меня есть дерево каталогов, подобное этому:

FOLDER:
    file1
    file2
    file3
    Subfolder1:
        file1
        file2
    Subfolder2:
        file1
        file2

Если бы я использовал rm -r FOLDER/*, все в FOLDER было бы удалено, включая подкаталоги. Как я могу удалить все файлы в папке FOLDER и в ее подкаталогах, не удаляя актуальные каталоги?

PKM
источник

Ответы:

37

То, что вы пытаетесь сделать, это рекурсивное удаление. Для этого вам понадобится рекурсивный инструмент, например find.

find FOLDER -type f -delete
Сергей Колодяжный
источник
13

С bash:

shopt -s globstar  ## Enables recursive globbing
for f in FOLDER/**/*; do [[ -f $f ]] && echo rm -- "$f"; done

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

Вышеуказанное является пробным прогоном, если его устраивают внесенные изменения, удалите echoдля фактического удаления:

for f in FOLDER/**/*; do [[ -f $f ]] && rm -- "$f"; done

Наконец, unset globstar:

shopt -u globstar

С zsh, используя глобус квалификатор:

echo -- FOLDER/**/*(.)

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

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

rm -- FOLDER/**/*(.)
heemayl
источник
2
+1 за зш бубинг. Все больше людей должны знать о том, что Zsh может сделать.
Marcelm
11

Если ваша версия findне поддерживает, -deleteвы можете использовать следующее, чтобы удалить все файлы в текущем каталоге и ниже.

find . ! -type d -exec rm '{}' \;

источник
-exec rm {} +будет быстрее, особенно если файлов много.
Муру
И find . ! -type d -exec rm {} +удаляет ссылки sym также.
Правосудие для Моники
1
@muru: Если конкретная реализация findне поддерживает, -deleteвероятно, тоже не поддерживает -exec ... {} +. Рекомендуемый способ справиться с этим find ... -print0 | xargs -r0 rm(если ожидается много потенциальных совпадений).
Дэвид Фёрстер
5
@DavidFoerster не совсем. -exec ... {} +это POSIX, но -deleteэто не так. ( -print0Кстати, нет.)
Муру
@ Муру: Достаточно справедливо. Я встречал, по крайней мере, две не-POSIX findреализации, которые поддерживали, -print0но не -exec ... {} +( -deleteхотя я не помню о них ). Один был на OS X, другой на Solaris (несколько лет назад в очень консервативно обновленной системе). Вы также можете заменить -print0на -printf '%p\0'. В любом случае, это Ask Ubuntu, а не Unix & Linux, и Ubuntu использует GNU find с тех пор, как это было всегда.
Дэвид Фёрстер