2013-01-08 12:17:05 +0000 2013-01-08 12:17:05 +0000
123
123

Como eliminar todos os ficheiros de um directório, excepto alguns?

Preciso de apagar todos os ficheiros de um directório, mas excluir alguns deles. Por exemplo, num directório com os ficheiros a b c ... z, preciso de apagar todos, excepto os u e p. Haverá uma maneira fácil de o fazer?

Respostas (17)

144
144
144
2013-01-08 12:34:49 +0000

Para rm todos menos u,p em bash apenas digite:

rm !(u|p)

Isto requer a seguinte opção a ser definida:

shopt -s extglob

Ver mais: glob - Greg’s Wiki

108
108
108
2013-01-08 12:18:23 +0000

O que faço nesses casos é digitar

rm *
``` 0x1& 

Depois pressiono Ctrl+X,\* para _expandir_ `*` em todos os nomes de ficheiros visíveis. 

Depois posso simplesmente remover os dois ficheiros que gosto de manter da lista e finalmente executar a linha de comando.
71
71
71
2013-01-08 12:35:05 +0000

Pode usar find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! nega a expressão seguinte
  • -name especifica um nome de ficheiro
  • -maxdepth 1 fará o processo de procura apenas no directório especificado (find por defeito atravessa directórios)
  • -type f processará apenas ficheiros (e não por exemplo directórios)
  • - -delete irá apagar os ficheiros

Poderá então afinar as condições olhando para a página man do find

Actualização

  • Tenha em mente que a ordem dos elementos das expressões é significativa (ver a documentação) & - Teste o seu comando primeiro usando -print em vez de -delete
43
43
43
2013-01-08 12:22:58 +0000

Simples:

mv os ficheiros que deseja num directório superior, rm o directório e depois mv eles de volta.

15
15
15
2013-01-08 14:22:21 +0000

Algo semelhante a esta resposta mas não são necessárias opções especiais, tanto quanto sei o seguinte é uma funcionalidade “antiga” suportada por qualquer (vagamente) /bin/sh que se assemelha a uma concha (por exemplo, bash, zsh, ksh, etc)

rm [^up]
11
11
11
2013-01-09 03:54:14 +0000

Fazendo-o sem encontrar:

ls | grep -v '(u|p)' | xargs rm

(Editar: “u” e “v”, como em outros lugares aqui, estão a ser usados como versões genéricas de regexes inteiros. Obviamente que vai querer ter o cuidado de ancorar os seus regexes para evitar a correspondência de demasiadas coisas).

Vai querer definitivamente um guião se vai fazer muito disto, como outros já sugeriram.

6
6
6
2013-01-09 22:34:13 +0000

Em zsh:

setopt extended_glob # probably in your .zshrc

depois

rm ^(u|p)

ou

rm *~(u|p)

O segundo funcionará mesmo que tenha ^ em $histchars para substituição da história, e claro que pode colocar um globo arbitrário antes do ~.

5
5
5
2013-01-08 16:32:06 +0000

GLOBIGNORE leva uma lista separada por cólon

GLOBIGNORE=u:p
rm *
3
3
3
2013-01-08 17:58:46 +0000
find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Isto irá apagar todos os ficheiros excepto u e p em unix

3
3
3
2013-01-08 17:02:15 +0000

Na época das disquetes tinha um dos executáveis chamado “Excepto” que movia as coisas para fora do directório actual temporáriamente e executava um comando, para que se pudesse dizer:

except \*.txt del \*.\*

para apagar tudo menos os seus ficheiros de texto.

Isto seria uma coisa bastante trivial para implementar como um script de shell e se este for o tipo de coisa que provavelmente fará mais do dobro, parece que seria uma boa ideia.

2
2
2
2013-01-08 18:16:45 +0000

Para aqueles que preferem especificar padrões de exclusão complexos arbitrários (abrangendo todos os nomes de ficheiros afectados) num estilo emacs, posix-awk ou posix-extended (ver página de encontrar homem), eu recomendaria este. Neste exemplo, exclui u e p no dir actual. Isto pode ser útil para os guiões.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
1
1
1
2014-09-24 03:05:26 +0000

Ainda outra:

for FILE in ./*; do if [[$FILE != ./u*]] || [[$FILE != ./p*]];then rm $FILE; fi; done;

É um pouco longo e não sei se poderia facilmente torná-lo numa função que poderia facilmente acomodar e um número arbitrário de argumentos, mas funciona bem.

E é pura bondade de bash.

1
1
1
2014-10-22 12:37:57 +0000

Aqui está outra variante. Pode digitar:

rm -i *

ou:

rm --interactive *

Assim, rm pedir-lhe-á que confirme a eliminação de cada ficheiro.

1
1
1
2016-09-11 02:33:03 +0000

Utilização:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

a fim de eliminar todos os ficheiros incluindo directórios, excepto ficheiros u, p e .ext.

1
1
1
2013-01-09 20:54:59 +0000

Eu utilizo sempre:

rm [a-o,q-t,v-z]*

Isto permitir-lhe-á definir a granularidade que pretende fazer. Assim, se quiser apagar ficheiros o e Z, pode utilizar:

rm [a-o,z]*
1
1
1
2013-04-01 12:44:13 +0000

Mais uma versão usando xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

Note-se que xargs -I é necessário para manusear correctamente os nomes de ficheiros incluindo espaços.

0
0
0
2013-10-22 07:06:44 +0000

Uma maneira simples que é difícil de estragar: digamos que quer apagar tudo excepto *.pdf:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp