1

Я пытаюсь понять мой старый навык в * nix.

То, чего я пытаюсь добиться - это удалить все папки, в которых нет определенного слова.

Это список

➜  myfolder: pwd
/user/myfolder

➜  myfolder: ll locale

drwxr-xr-x  3 user  staff  102 23 Oct 11:13 bn_BD
drwxr-xr-x  3 user  staff  102 23 Oct 11:13 bn_IN
drwxr-xr-x  3 user  staff  102 22 Oct 19:03 en_CA
drwxr-xr-x  8 user  staff  272  9 Dec 16:10 en_US
drwxr-xr-x  3 user  staff  102 22 Oct 19:03 es
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 fr
drwxr-xr-x  3 user  staff  102 23 Oct 11:13 pt
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 ru
drwxr-xr-x  3 user  staff  102 21 Oct 13:18 th_TH

Теперь я хочу удалить все, кроме en_US

Я не знаю, что не в команде

rm -rf locale/[!somethinghere]

4 ответа4

3

С помощью GNU find (и, возможно, других версий) вы можете использовать восклицательный знак, чтобы отменить поиск - так что вы найдете и удалите все в текущем каталоге, кроме 'en_us':

find . ! -name 'en_US' -delete
##  If you only want to delete directories:
find . -type d ! -name 'en_US' -delete
##  If you *don't* want recursiveness:
find . -maxdepth 1 -type d ! -name 'en_US' -delete
##  If you want to avoid deleting dotfiles:
find . -maxdepth 1 -type d ! -name 'en_US' -a ! '.*' -delete

Некоторые версии find не имеют опции -delete ; вместо этого вы можете использовать один из:

find . -maxdepth 1 -type d ! -name 'en_US' -exec rm -r '{}' +
find . -maxdepth 1 -type d ! -name 'en_US' -a ! '.*' -exec rm -r '{}' +

Кроме того, так как вы упомянули в комментарии, что у вас есть Zsh,

setopt extendedglob  ##  this may already be set in you .zshrc
rm ^*en_US*
##  If you only want to delete directories:
rm ^*en_US*(/)
1

Будет работать трехстрочное решение (протестировано с Linux bash):

tar cvf foo $(find locale -name en_US)
rm -fr locale
tar xvf foo

То есть:

  • Сохранить то, что вы хотите сохранить
  • Удалить оригинал
  • Восстановите то, что вы сохранили

Я поиграл с чем-то вроде find locale \( -name en_US -true \) -o -print | xargs ... , но это кажется более сложным. И более рискованно, если ваши навыки Unix ржавые.

0

Вы можете сделать это используя расширение bash:rm -rf path/to/!(something.*)

Редактировать:

Как упомянуто в комментариях ниже, эта команда работает, если включен расширенный формат globbing .

Вы можете включить его командой shopt -s extglob в bash или setopt kshglob в zsh.

0

Это то, что я в итоге делаю.

find locale -type d ! -name 'en_US' ! -name 'locale' | xargs rm -rf

Причина, по которой я должен включить "locale", потому что xargs вернул locale locale/bn_BD locale/bn_IN locale/en_CA locale/es locale/fr locale/pt locale/ru locale/th_TH

Теперь я удалил эти

#   deleted:    locale/bn_BD/goggles.webmaker.org.json
#   deleted:    locale/bn_IN/goggles.webmaker.org.json
#   deleted:    locale/en_CA/goggles.webmaker.org.json
#   deleted:    locale/es/goggles.webmaker.org.json
#   deleted:    locale/fr/goggles.webmaker.org.json
#   deleted:    locale/pt/goggles.webmaker.org.json
#   deleted:    locale/ru/goggles.webmaker.org.json
#   deleted:    locale/th_TH/goggles.webmaker.org.json

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .