Удалить все каталоги из родительского каталога, кроме одного и его потомков
4 ответа
Что вы хотите, это команда:
find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
Демо-версия:
# List what's inside directory we want to remove
$ ls
file1 file2 keepMe/ removeA/ removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1 file2 keepMe/
Объяснение:
find DIRECTORY
команда call find для работы с DIRECTORY-mindepth 1
: работать только с содержимым каталога, избегать самого каталога уровня 0-maxdepth 1
: предотвращает спуск в подкаталоги (rm -rf
в любом случае является рекурсивным, поэтому нам не нужно спускаться в подкаталоги, чтобы удалить их)-type d
: поиск только по каталогам-not \( -name "keepMe" \)
игнорировать элемент с именем, которое вы хотите сохранить-exec rm -rf {} \;
выполнить удаление на каждом найденном предмете
Использование расширенных функций glob оболочки bash (которые включены по умолчанию в текущих установках Ubuntu), учитывая
$ tree A
A
├── B
├── C
│ ├── ac1
│ └── ac2
└── D
5 directories, 0 files
Вы можете обратиться ко всему, кроме C
и его содержимое с использованием выражения glob A/!(C)
т.е.
$ echo A/!(C)
A/B A/D
Таким образом, чтобы удалить все, кроме каталога C
и его содержимое вы можете просто использовать
rm -rf A/!(C)
уход
$ tree A
A
└── C
├── ac1
└── ac2
3 directories, 0 files
Одним из простых способов было бы использовать trash-cli
Вы можете установить его с sudo apt-get install trash-cli
После установки вы можете перейти в родительский каталог A с помощью cd /A
а затем выполните командуtrash B D
где B и D - каталоги, которые вы хотите удалить (они попадут в корзину для диска, на котором они находятся, поэтому, если вы допустите ошибку, вы сможете восстановить файлы)
Протестировано под Ubuntu 16.04 и 14.04
Просто используйте Баш for
петля и test
фильтровать нужные каталоги и rm -rf
Команда для рекурсивного удаления каталогов, например так:
for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done
Это перебирает все элементы (файлы и каталоги) внутри /path/to/parent/
и удаляет элемент рекурсивно, если его имя не равно dir_survive
, Если родительский каталог является текущим каталогом, вы можете написать только *
как путь.
Если вы не уверены и хотите сначала проверить, какие элементы будут удалены без каких-либо действий, просто замените rm -rf
в приведенной выше команде с echo
и он будет только выводить кандидатов на удаление.
Вот пример запуска:
$ tree
.
├── dir1
│ ├── subdir1
│ │ ├── file1
│ │ └── file2
│ └── subdir2
│ ├── file1
│ └── file2
├── dir2
│ ├── subdir1
│ │ ├── file1
│ │ └── file2
│ └── subdir2
│ ├── file1
│ └── file2
└── dir_survive
├── subdir1
│ ├── file1
│ └── file2
└── subdir2
├── file1
└── file2
9 directories, 12 files
$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done
$ tree
.
└── dir_survive
├── subdir1
│ ├── file1
│ └── file2
└── subdir2
├── file1
└── file2
3 directories, 4 files