Exclua todos os subdiretórios, exceto um

10

Suponha que, no diretório atual, existam vários subdiretórios e um seja chamado A.

Como excluir todos os subdiretórios, exceto A, com o Bash?

anon
fonte

Respostas:

23

O Bash estendeu o globbing (primeiro teste e remova o eco):

shopt -s extglob
echo rm -rf !(A)
TheBonsai
fonte
(antes que me esqueça - você pode desativar a conclusão história estilo CSH, em Bash3 há um bug, ignorando (set + H!.
+1 Bash se cheio de surpresas! Às vezes eles são legais como este.
Aleksandr Levchuk
Wauw muito bom mesmo! Funciona como esperado. Com shopt | grep extVocê pode ver se o plug-in está ativado.
usar o seguinte comando
14
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
dotjoe
fonte
10

A respeito:

mv A /tmp/
rm * -rf
mv /tmp/A .

Isso evita parte da "escassez" de um erro de digitação nos outros comandos.

Brent
fonte
1
+1 por fazer a coisa certa, em vez de esperar que as ferramentas sejam suficientemente inteligentes. Ainda assim, uma noite, quando eu estava apenas aprendendo Linux, copiei o kernel para / tmp antes de fazer minha primeira recompilação. não foi bem-sucedido, mas apaguei o antigo, então eu disse 'não se preocupe, tenho uma cópia' apenas para descobrir que uma tarefa cron da meia-noite a apagara com todos os arquivos com mais de uma semana em / tmp! eu tive que recompilar novamente e desta vez fazê-lo corretamente, ou não reinicialize para mim!
Javier
melhor resposta postada :)
warren
3

Algo como

find . -type d -not -name A -exec rm -ir {} \;

deveria fazer.

editar

Realmente deveria ser

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

impedir que se findrepita abaixo de A.

agnul
fonte
3
Mas isso também removeria todos os subdiretórios abaixo de A como A / foo e A / bar, mas preservaria o A / A.
6606 TCampbell
Legal! Perguntas e answert get migrou do SO para SF ... mas a minha edição anterior foi perdido ...
agnul
Deve ser melhor trocar maxdepth e digitar argumentos como este: find. -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
Spawnrider 11/02/19
1

Eu costumo fazer isso trabalhando com um comando ls que acerta primeiro. não estou em uma máquina unix, mas algo como:

ls -lda "[^ A]"

Depois de acertar, canalize-o para um comando

ls -lda "[^ A]" | xargs rm -rf

Sinta-se à vontade para editar acima se minha expressão regular estiver errada ...

Tim Hoolihan
fonte
Você não deve analisar sl: mywiki.wooledge.org/ParsingLs
Pausado até novo aviso.
1

Se você quiser ser mais flexível, mas manual, você pode fazer:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

Dessa forma, você pode fazer mudanças gerais.

Joe Beda
fonte
1

Aqui está uma maneira. Tenha cuidado com esse tipo de coisa, porém, é tão poderoso que só pode ser usado para o bem ou para o mal ...

encontre * -tipo d | grep -v "^ A" | xargs rm -rf
Don Branson
fonte
1

Não use find, como algumas pessoas mostraram com -exec e rm sem passar -print0 para localizar e -0 para xargs. Ficará confuso nos nomes dos arquivos com espaços ou novas linhas:

$ 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

Em vez disso, use find -print0 com xargs -0, '-exec command {} +' ou -delete se a sua localização suportar.

Kyle Brandt
fonte
1

Além do exemplo anterior de:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

você também pode fazer:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

para evitar ter que cd some/subdirprimeiro.

Lurchman
fonte