Como excluir todas as subpastas de primeiro nível que não possuem uma string especificada em seus nomes

3

Eu sei que há muitas perguntas respondidas sobre como excluir todos os arquivos com ou sem uma determinada string em seus nomes , bem como sobre como excluir todas as subpastas com uma determinada string em seus nomes.

No entanto, não há perguntas sobre como excluir todas as subpastas sem uma determinada string nesses nomes.

Então, como recentemente tive esse problema, há um comando rápido que ajudará nessa situação? Um script bash seria bom o suficiente também.

EDITAR :

Por subpastas , quis dizer apenas as subpastas de primeiro nível, porque não quero remover subpastas de segundo nível ou terceiro nível, que podem ter nomes sem a cadeia de caracteres, de subpastas de nível com a string.

    
por PyGeek03 16.07.2016 / 11:37

2 respostas

9

Digamos que você queira iniciar find no diretório atual e restringi-lo ao primeiro nível de subdiretórios:

find . -maxdepth 1

O comando find tem um sinalizador útil -not (ou ! ), que nega o seguinte teste. Então, para encontrar um nome que não contenha uma substring, adicione

-not -name "*substring*"

IMPORTANTE: você também desejará excluir o diretório atual. Caso contrário, todo o diretório atual seria excluído.

-not -name "."

Então você quer testar somente os diretórios:

-type d

E, se tudo parece bem, você deseja excluir esses diretórios:

-exec rm -rf {} \;

que diz "para todos os diretórios encontrados, execute este comando". O {} é um espaço reservado para o nome do diretório (incluindo o caminho completo, para que funcione no caminho correto). \; indica o final do comando a ser executado.

Resumindo:

find . -maxdepth 1 -not -name "*substring*" -not -name "." -type d -exec rm -rf {} \;

deve funcionar. Mas primeiro, experimente sem a parte -exec .

    
por Jos 16.07.2016 / 12:34
4

Os operadores glob estendido do bash shell podem fazer negação de padrão, por exemplo dado

$ tree .
.
├── subdir
│   ├── other file
│   └── somefile
├── subdirbar
│   ├── other file
│   └── somefile
├── subdirbaz
│   ├── other file
│   └── somefile
└── subdirfoo
    ├── other file
    └── somefile

4 directories, 8 files

então se a globalização estendida estiver ativada ( shopt -s extglob )

$ rm -rf !(*foo*)

remove (recursivamente) todos os diretórios de nível superior que não contêm a string foo , deixando

$ tree
.
└── subdirfoo
    ├── other file
    └── somefile

1 directory, 2 files

No entanto , isso também excluiria arquivos com nomes que não contenham foo no nível superior. AFAIK bash extended globs não consegue distinguir arquivos de diretórios - mas o zsh fornece qualificadores de glob , que permitem que, e. dado

 % tree
.
├── foofile
├── other file
├── somefile
├── subdir
│   ├── other file
│   └── somefile
├── subdirbar
│   ├── other file
│   └── somefile
├── subdirbaz
│   ├── other file
│   └── somefile
└── subdirfoo
    ├── other file
    └── somefile

4 directories, 11 files

e, em seguida, em zsh

 % setopt EXTENDED_GLOB

 % ls -d (^(*foo*))   
other file  somefile  subdir  subdirbar  subdirbaz

ao adicionar o qualificador de diretório (/)

 % ls -d (^(*foo*))(/)
subdir  subdirbar  subdirbaz

então

 % rm -rf (^(*foo*))(/)

remove somente os diretórios cujos nomes não incluem a string foo , deixando os arquivos simples intactos.

 % tree
.
├── foofile
├── other file
├── somefile
└── subdirfoo
    ├── other file
    └── somefile

1 directory, 5 files
    
por steeldriver 16.07.2016 / 13:55