Como removo todos os arquivos de uma pasta, exceto apenas alguns arquivos especificados?

11

Eu quero remover todos os arquivos em um diretório, deixando apenas alguns arquivos especificados, eles não têm nada em comum por nome. Como eu consegui isso?

Por exemplo, os nomes de arquivo que eu quero manter são:

file_1.png, another_file.jpg,some_music.mp3

AGamePlayer
fonte

Respostas:

14

Se você estiver usando o bash:

shopt -s extglob
rm -- !(file1|file2|file3)

A primeira linha apenas ativa a correspondência estendida de padrões e, depois disso, usamos um deles:

!(pattern-list) corresponde a qualquer coisa, exceto um dos padrões fornecidos

e a lista de padrões é uma lista de um ou mais padrões separados por a |.


Ou com zsh

setopt extendedglob
rm -- ^(file1|file2)

Ou, mais portátil, usando find:

find . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -v {} +
jimmij
fonte
3
Pode ser útil incluir como retornar o comportamento opcional do shell de volta ( shopt -u extglob).
precisa saber é o seguinte
7

Crie um subdiretório tmp, mova todos os arquivos que você deseja manter para esse diretório e faça rm -f *depois. Isso não afetará o tmpdiretório.

Depois disso basta fazer:

mv tmp/* .
rmdir tmp

(Supondo que nenhum dos arquivos que você moveu comece com um ponto).

Este é um dos poucos casos em que faz sentido usar o mouse e um navegador de arquivos como o Nautilus, onde você pode realmente Ctrlclicar nos poucos arquivos que deseja manter e usar o menu: Edit -> Invert Selectionpara obter os outros arquivos e excluí-los .

Anthon
fonte
o movimento de arquivos para o diretório tmp parece bom. Enfim, eu tenho que fazer isso com a linha de comando. Obrigado!
AGamePlayer
3
@AwQiruiGuo O tmp tem a vantagem de separar primeiro os arquivos em dois conjuntos, antes de remover irrevogavelmente os que você não deseja. Assim, você pode executar um lspara ver se não perdeu nenhum dos arquivos que deseja preservar.
Anthon
2

Adicione os nomes dos arquivos que você deseja manter em um arquivo de texto, um por linha. Este arquivo não deve estar no diretório ou você deve adicionar seu nome também.

Se o nome do seu diretório for foo e o nome do arquivo for bar , faça o seguinte.

find foo -type f -print0|grep -vzZ -f bar|xargs -0 rm

Isso faz o seguinte:

  1. find -type fprocura os nomes de todos os arquivos em foo e seus subdiretórios e os imprime em STDOUT. Com a opção -print0delimita os nomes de arquivos com NUL bytes.
  2. grep -v -f barexclui todos os nomes de arquivos que correspondem a uma linha na barra . Com a opção -z, trata sua entrada como um conjunto de linhas delimitadas por byte NUL, com opção -Zdelimita sua saída com um byte NUL.
  3. xargs rmchama rmrepetidamente para excluir os arquivos. Com a opção -0, trata sua entrada como um conjunto de linhas delimitadas por byte NUL.

Isso funciona com nomes de arquivos que contêm espaço em branco.

Mathias Weidner
fonte
Isso não funcionará, pois os nomes de arquivos podem ter novas linhas.
Anthon
@Anthon alterado as opções de encontrar, grep, xargs para lidar com nomes de arquivos que contenham espaços em branco, incluindo novas linhas
Mathias Weidner
Se você quiser usar findEu preferiria fazerfind . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -vi {} +
jimmij