Мой каталог верхнего уровня - data
. data
включает в себя несколько каталогов, и эти каталоги имеют подкаталоги. Мне нужно удалить все файлы и каталоги внутри data/
, кроме нескольких файлов в некоторых каталогах.
Например, данные включают в себя каталоги 100
и 101
. Я просто хочу сохранить файлы a.txt
и b.txt
в 100/
и c.txt
и d.txt
в 101/
, удаляя все остальные файлы и каталоги в 100
и 101
.
Пример:
.
├── 100
│ ├── a.txt
│ ├── b.txt
│ ├── c.txt
│ └── d.txt
└── 101
├── a.txt
├── b.txt
├── c.txt
└── d.txt
Я использую команду rm -rf !(a.txt|b.txt)
, но не могу применить эту команду для каждого каталога автоматически.
Как Вы уже узнали, можно использовать extglob
опция, которая активирована с:
shopt -s extglob
Это позволяет исключать соответствия так, чтобы можно было сделать вещи как:
rm 100/!([ab].txt) 101/!([cd].txt)
Это - хорошая идея протестировать его с echo
сначала. Этот пример будет соответствовать чему-либо внутри 100/
который не является a.txt
или b.txt
и что-либо внутри 101/
который не является c.txt
или d.txt
. Если те же правила для 100/
обратиться 102/
также можно сделать, например:
10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
Вы могли использовать find
для этого. Можно инвертировать тесты в find
с -not
или !
. Это исключит соответствия, вместо того, чтобы найти их.
Необходимо бояться удалять любой из родительских каталогов файлов, которые Вы хотите сохранить, особенно текущий каталог .
, поэтому удостоверьтесь, что Вы читаете вывод полностью перед удалением.
На основе Вашего примера Вы могли сделать что-то вроде этого от data
каталог.
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"
Добавьте a ! -path ./path/to/dir
для любого пути Вы не хотите удалять. Можно использовать метасимволы как *
, но удостоверьтесь, что Вы заключаете выражение в кавычки, если Вы делаете, например, "./path*dir"
, предотвратить любые нежелательные расширения.
find
является рекурсивным по умолчанию. Даже если мы не находим ./100
здесь, мы найдем все его содержание, если они не будут соответствовать шаблону [ab].txt
. Если Вы не можете соответствовать всем именам, Вы хотите сохранить, добавить другой тест:
! -path "./100/[ab].txt" ! -path ./100/foo
Это не найдет a.txt
или b.txt
или foo
, но это найдет все другие файлы.
Когда Вы уверены, что видите то, что Вы хотите, можно добавить -delete
в конец удалить найденные файлы:
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete