Удалить все каталоги из родительского каталога, кроме одного и его потомков

Я хочу удалить каталог B и D. Но я хочу сохранить C и все его дочерние файлы и каталоги. Что такое команда для удаления всех дочерних каталогов родительского каталога, кроме одного каталога и его дочерних.

Помощь приветствуется.

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
Другие вопросы по тегам