Предположим, что в текущем каталоге есть несколько подкаталогов, один из которых называется A.
Как удалить все подкаталоги, кроме A, с помощью Bash?
В Bash есть расширенные возможности подстановки (сначала проверьте, затем удалите эхо):
shopt -s extglob
echo rm -rf !(A)
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
Что о:
mv A /tmp/
rm * -rf
mv /tmp/A .
Это позволяет избежать некоторых "пугающих" опечаток в других командах.
Что-то вроде
find . -type d -not -name A -exec rm -ir {} \;
стоит сделать.
редактировать
Это действительно должно быть
find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;
предотвращать find
от рекурсии ниже A.
Обычно я делаю это, создавая команду ls, которая сначала делает все правильно. я не на машине unix, но что-то вроде:
ls -lda "[^ A]"
Как только вы сделаете это правильно, передайте его команде
ls -lda "[^ A]" | xargs rm -rf
Не стесняйтесь редактировать выше, если у меня неправильное регулярное выражение ...
Если вы хотите быть более гибким, но ручным, вы можете:
ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r
Таким образом, вы можете делать общие манипуляции.
Вот один способ. Но будьте осторожны с подобными вещами, они настолько сильны, что могут быть использованы только во благо или во зло ...
find * -type d | grep -v "^A" | xargs rm -rf
Не используйте find, как некоторые люди показали с -exec и rm, без передачи -print0 для поиска и -0 для xargs. Он запутается в именах файлов с пробелами или символами новой строки:
$ mkdir 'foo foo'
$ mkdir foo$'\n'foo
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory
Вместо этого используйте find -print0 с xargs -0, '-exec command {} +' или -delete, если ваша находка поддерживает это.
Смотрите также здесь:
В дополнение к предыдущему примеру:
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
вы также можете:
find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
чтобы избежать необходимости cd some/subdir
первый.