У меня есть папка, содержащая множество папок и различных файлов со следующей структурой:
NASA
│
├── a
│ ├── doc1
│ ├── doc2
│ ├── doc3
│ ├── folder1
│ └── folder2
│
├── b
│ ├── doc1
│ ├── doc2
│ ├── doc3
│ ├── folder1
│ └── folder2
│
├── c
│ ├── doc1
│ ├── doc2
│ ├── doc3
│ ├── folder1
│ └── folder2
│
├─ x
├─ y
└─ z
Я хочу удалить содержимое папки ( NASA/
), за исключением указанных папок и файлов.
Например, я хочу сохранить a
папку, b
папку и x
файл.
Я пыталсяэто решение :
rm !(a/) -r NASA/
И (как объяснено в ответе)здесь):
find NASA/ -type f ! -iname "x" -delete
Но это не очень просто, и мне придется использовать bash-скрипт.
Я упускаю более простой способ? Как это сделать одной командой?
решение1
Вы можете использовать GLOBIGNORE
для установки имен, которые будут игнорироваться при глобализации, а затем использовать их *
для сопоставления со всеми остальными файлами/каталогами:
GLOBIGNORE='a:b:x'; rm -r *
Пример:
$ tree
.
├── a
│ ├── 1
│ ├── 2
│ └── 3
├── b
│ ├── 1
│ ├── 2
│ └── 3
├── c
│ ├── 1
│ ├── 2
│ └── 3
├── x
├── y
└── z
/NASA$ GLOBIGNORE='a:b:x'
/NASA$ rm -r *
/NASA$ tree
.
├── a
│ ├── 1
│ ├── 2
│ └── 3
├── b
│ ├── 1
│ ├── 2
│ └── 3
└── x
В качестве альтернативы вы можете использовать find
из NASA
каталога:
find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +
Пример:
/NASA$ tree
.
├── a
│ ├── 1
│ ├── 2
│ └── 3
├── b
│ ├── 1
│ ├── 2
│ └── 3
├── c
│ ├── 1
│ ├── 2
│ └── 3
├── x
├── y
└── z
/NASA$ find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +
/NASA$ tree
.
├── a
│ ├── 1
│ ├── 2
│ └── 3
├── b
│ ├── 1
│ ├── 2
│ └── 3
└── x
решение2
Вы можете использовать расширенную подстановку, но восклицательный знак исчезнет.дошаблон:
rm -rf NASA/!(a|b|x)
Если extglob
он не включен, сначала активируйте его:
shopt -s extglob