Remove todas as pastas que não contêm um nome específico no UNIX

1

Estou tentando descobrir minha antiga habilidade em * nix.

O que estou tentando alcançar é remover todas as pastas que não contêm uma palavra específica.

Esta é a listagem

➜  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

Agora quero remover tudo, exceto en_US

Eu não sei o que não está no comando

rm -rf locale/[!somethinghere]

    
por Ali 09.12.2013 / 22:25

4 respostas

3

Com o GNU find (e possivelmente outras versões também), você pode usar um ponto de exclamação para reverter uma pesquisa - assim, ele encontrará e excluirá tudo no diretório atual exceto '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

Algumas versões do find não têm a opção -delete ; em vez disso, você poderia usar um de:

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

Alternativamente, desde que você mencionou em um comentário que você tem zsh,

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

Uma solução de três linhas funcionará (testada com o bash do Linux):

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

Isto é:

  • Salve o que você deseja manter
  • Excluir original
  • Restaurar o que você salvou

Brinquei com algo como find locale \( -name en_US -true \) -o -print | xargs ... , mas isso parece mais complicado. E mais arriscado, se as habilidades do Unix estiverem enferrujadas.

    
por 09.12.2013 / 23:29
0

Isso é o que eu acabo fazendo.

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

A razão pela qual eu tenho que incluir "locale" também porque o xargs retornou locale locale/bn_BD locale/bn_IN locale/en_CA locale/es locale/fr locale/pt locale/ru locale/th_TH

Agora eu tenho esses excluídos

#   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
    
por 10.12.2013 / 00:14
0

Você pode fazer isso usando a expansão do bash: rm -rf path/to/!(something.*)

Editar:

Como mencionado nos comentários abaixo, este comando funciona se o formato globbing estendido estiver ativado.

Você pode ativá-lo pelo comando shopt -s extglob em bash ou setopt kshglob em zsh .

    
por 09.12.2013 / 23:17