Найдите и удалите все каталоги с именем «test» в Linux

35

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

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

find . -name test -print

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


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

вывоз мусора
источник

Ответы:

70

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решению.)

Арно Ле Блан
источник
1
Отличный ответ, особенно +в поиске. Я понятия не имел, определенно хотел бы знать это давно.
Скотт
следите за последней командой, каким-то образом она удалила некоторые файлы. xargsкоманда работала хорошо.
Энрике де Соуза
23
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 {} \;

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

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

Джайпал Сингх
источник
1
Извините, я забыл упомянуть, что эти каталоги могут иметь файлы. Не удалось удалить некоторые из них из-за ошибки «найти: невозможно удалить` ./start ': каталог не пуст »
сборка мусора
@garbagecollection Я добавил обновление.
Джайпал Сингх
3
Вы можете использовать +вместо того, \;чтобы передавать более одного каталога за раз.
JFS
Спасибо @JFSebastian Хороший вопрос. Я добавлю это в ответ.
Джайпал Сингх
5

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

find . -name test -exec rm {} \;
Sethi
источник
3

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

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

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

printf '%s\n' ./**/test/
evilsoup
источник
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
Карл
источник