31

У меня есть много каталогов с именем "test", и я хотел бы удалить их.

Я знаю, как их найти и распечатать, используя:

find . -name test -print

Теперь, как мне удалить каталоги?


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

7 ответов7

66

xargs делает всю магию:

find . -name test -type d -print0|xargs -0 rm -r --

xargs выполняет команду, переданную в качестве параметров, с аргументами, передаваемыми в stdin.

Это использует rm -r для удаления каталога и всех его дочерних элементов.

Знак -- обозначает конец аргументов, чтобы избежать тракта, начинающегося с - который рассматривается как аргумент.

-print0 указывает find для печати \0 символов вместо новых строк; и -0 указывает xargs обрабатывать только \0 как разделитель аргументов.

Это вызывает rm со многими каталогами одновременно, избегая затрат на вызов rm отдельно для каждого каталога.


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

find . -name test -type d -exec rm -r {} \;

И этот, с лучшей производительностью, так как он будет вызывать rm с несколькими каталогами одновременно:

find . -name test -type d -exec rm -r {} +

(Обратите внимание на + в конце; это эквивалентно решению xargs .)

21
find /path/to/dir -name "test" -type d -delete
  • -name: ищет переданное имя. Вы можете использовать -regex для предоставления имен на основе регулярных выражений

  • -type: ищет типы файлов. d только каталоги

  • -delete: действие, которое удаляет найденный список.

В качестве альтернативы:

find /path/to/dir -name "test" -type d -exec rm -rf {} \;

Как сказал в комментариях Дж. Ф. Себастьян :

Вы можете использовать + вместо \; пропустить более одного каталога за раз.

7

еще один способ сделать это

find . -name test -exec rm -R "{}" \;

Полезная ссылка на поиск: http://www.softpanorama.info/Tools/Find/using_exec_option_and_xargs_in_find.shtml

5

Вы также можете использовать опцию -exec

find . -name test -exec rm {} \;
2

Предположим, вы используете gnu find, вы можете использовать опцию -delete:

find . -name test -delete

что легче запомнить.

2

Как указывает другой ответ, вы можете попытаться найти все каталоги с именем test и удалить их

find -name "test" -type d -delete

Я столкнулся с некоторыми проблемами с перекрестной совместимостью на Mac, поэтому я использовал эту эквивалентную команду:

find -path "*/test" -type d -delete
  • -path: ищет шаблон в полном имени файла.

Однако в любом случае, если в каком-либо из каталогов с именем test есть файлы, find , что Directory is not empty , и не удастся удалить каталог.

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

find -path "*/test/*" -delete

Шаблон "*/test/*" гарантирует, что мы удаляем файлы только в каталоге с именем /test/ . Когда каталоги пустые, мы можем удалить каталоги с помощью первой команды:

find -path "*/test" -type d -delete

Пример:

$ tree
.
├── mytest
│   └── test
│       └── blah.txt
├── test
│   ├── bar.jpg
│   └── dir
│       └── bar.bak
└── testdir
    └── baz.c

5 directories, 4 files

$ find -path "*/test" -type d -delete
$ tree
.
├── mytest
│   └── test
├── test
└── testdir
    └── baz.c

4 directories, 1 file

$ find -name "test" -type d -delete
$ tree
.
├── mytest
└── testdir
    └── baz.c

2 directories, 1 file
2

Предполагая Bash 4+

shopt -s globstar
rm -r ./**/test/

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

printf '%s\n' ./**/test/

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