Como apagar todos os arquivos em um diretório, exceto alguns?

119

Eu preciso excluir todos os arquivos em um diretório, mas excluir alguns deles. Por exemplo, em um diretório com os arquivos a b c ... z , preciso excluir todos, exceto u e p . Existe uma maneira fácil de fazer isso?

    
por Ashot 08.01.2013 / 13:17

17 respostas

108

O que eu faço nesses casos é digitar

rm *

Em seguida, pressiono Ctrl + X , * para expandir * em todos os nomes de arquivos visíveis.

Então eu posso apenas remover os dois arquivos que eu gosto de manter na lista e finalmente executar a linha de comando.

    
por 08.01.2013 / 13:18
143

Para rm all mas u,p no bash apenas digite:

rm !(u|p)

Isso requer que a seguinte opção seja definida:

shopt -s extglob

Veja mais: glob - Wiki do Greg

    
por 08.01.2013 / 13:34
68

Você pode usar find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! nega a próxima expressão
  • -name especifica um nome de arquivo
  • -maxdepth 1 fará com que o processo de localização apenas o diretório especificado ( find por padrão atravessa diretórios)
  • -type f processará apenas arquivos (e não, por exemplo, diretórios)
  • -delete excluirá os arquivos

Você pode ajustar as condições olhando a página do manual do

Atualizar

  • Lembre-se de que a ordem dos elementos das expressões é significativa (consulte a documentação)
  • Primeiro, teste seu comando usando -print em vez de -delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print
    
por 08.01.2013 / 13:35
42

Simples:

mv os arquivos que você deseja em um diretório superior, rm do diretório e, em seguida, mv de volta.

    
por 08.01.2013 / 13:22
15

Um pouco semelhante a esta resposta , mas não são necessárias opções especiais, até onde eu saiba o seguinte é "antigo" funcionalidade suportada por qualquer shell (vagamente) / bin / sh (por exemplo, bash, zsh, ksh, etc)

rm [^up]
    
por 08.01.2013 / 15:22
11

Fazendo isso sem encontrar:

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

(Edit: "u" e "v", como em outros lugares aqui, estão sendo usados como versões genéricas de regexes inteiras. Obviamente, você vai querer ter cuidado para ancorar seus regexes para evitar combinar muitas coisas.)

Você definitivamente vai querer um roteiro se for fazer muito disso, como outros sugeriram.

    
por 09.01.2013 / 04:54
6

No zsh:

setopt extended_glob  # probably in your .zshrc

então

rm ^(u|p)

ou

rm *~(u|p)

O segundo funcionará mesmo se você tiver ^ em $histchars para substituição de histórico e, é claro, você pode colocar um globo arbitrário antes do ~ .

    
por 09.01.2013 / 23:34
5

GLOBIGNORE pega uma lista separada por dois pontos

GLOBIGNORE=u:p
rm *
    
por 08.01.2013 / 17:32
3

De volta à era do disquete Eu tinha um dos executável chamado "Excepto" que moveria as coisas do diretório atual temporariamente e executaria um comando, assim você poderia dizer:

except *.txt del *.*

para excluir tudo, exceto seus arquivos de texto.

Isso seria uma coisa bem trivial para implementar como um script de shell e se esse é o tipo de coisa que você provavelmente fará mais do que duas vezes, parece que seria uma boa ideia.

    
por 08.01.2013 / 18:02
3
 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Isto irá deletar todos os arquivos, exceto o u e o p no unix

    
por 08.01.2013 / 18:58
2

Para aqueles que preferem especificar padrões de exclusão complexos arbitrários (abrangendo todos os nomes de arquivos afetados) em um estilo completo eexs regexp, posix-awk ou posix-extended (consulte a página man man), eu recomendaria este. Exclui u e p no diretório atual neste exemplo. Isso pode ser útil para scripts.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
    
por 08.01.2013 / 19:16
1

Eu sempre uso:

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

Isso permitirá que você defina como você deseja granular. Então, se você quiser excluir os arquivos z e o, você pode usar:

rm [a-o,z]*
    
por 09.01.2013 / 21:54
1

Ainda outra versão usando xargs :

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

Observe que xargs -I é necessário para manipular nomes de arquivos, incluindo espaços corretamente.

    
por 01.04.2013 / 14:44
1

Ainda outro:

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

É um pouco longo e não sei se você poderia facilmente transformá-lo em uma função que pudesse acomodar facilmente um número arbitrário de argumentos, mas funciona bem.

E é pura bondade do bash.

    
por 24.09.2014 / 05:05
1

Aqui está outra variante. Você pode digitar:

rm -i *

ou:

rm --interactive *

Portanto, rm solicitará que você confirme a exclusão de cada arquivo.

    
por 22.10.2014 / 14:37
1

Uso:

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

para excluir todos os arquivos, incluindo diretórios, exceto os arquivos u, p e .ext.

    
por 11.09.2016 / 04:33
0

Uma maneira simples que é difícil de estragar: digamos que você queira excluir tudo, exceto * .pdf:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp
    
por 22.10.2013 / 09:06

Tags