Como removo vários arquivos com um prefixo e sufixo comum?

21

Tenho muitos arquivos nomeados

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

e arquivos chamados

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

e arquivos chamados

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

e

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Eu só quero remover os arquivos que começam com 'sequence_1' e terminam em '.hmf', mas não quero removê-los um por um, pois existem milhares de arquivos. Como posso especificar para o comando rm que desejo remover tudo o que começa com o prefilx 'sequence_1' e termina em '.hmf'?

Atualmente, estou trabalhando com um sistema RedHat Linux, mas gostaria de saber como fazer isso em outras distribuições também.

Paulo
fonte

Respostas:

28
rm sequence_1*.hmf

remove arquivos começando com sequence_1e terminando com .hmf.


Globbing é o processo no qual seu shell pega um padrão e o expande para uma lista de nomes de arquivos que correspondem a esse padrão. Não confunda com expressões regulares, que são diferentes. Se você passa a maior parte do tempo bash, o Wooledge Wiki possui uma boa página sobre globbing (expansão do nome do caminho) . Se você deseja portabilidade máxima, também deve ler a especificação POSIX sobre correspondência de padrões .


No caso improvável de você encontrar um erro "A lista de argumentos é muito longa" , consulte o BashFAQ 95 , que trata disso. A solução mais simples é dividir o padrão glob em vários pedaços menores, até que o erro desapareça. No seu caso, você provavelmente poderia dividir a correspondência pelos dígitos de prefixo 0 a 9, da seguinte maneira:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case
jw013
fonte
Este é um trabalho muito inteligente para contornar o erro 'lista de argumentos muito longa'. No meu caso, eu tenho vinte mil arquivos, então acho que precisaria usar um loop for de 0, ..., 20. Direita?
Paul
@Paul Certo, basta dividir a lista em quantos blocos você precisar, embora em algum momento a findabordagem se torne mais fácil do que adivinhar e checar.
jw013
14

Embora a resposta de jw013 seja correta, este comando pode falhar se você tiver milhares de correspondências: a linha de comando expandida rm sequence_1_0001.hmf sequence_1_0002.hmf ...gerada pelo shell pode ser simplesmente muito grande.

Como sugerido pelo Dom, você também pode usar a -deleteopção com find:

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

Ambos -maxdepthe -delete, embora não estejam no padrão POSIX, são bastante comuns em findimplementações na natureza. As distribuições Linux geralmente usam o GNU find, que certamente suporta essas opções.

Sem utilidade
fonte
2
Se você puder, use a opção -delete para achado, não desembolsar para cada arquivo ...
Dom
Adicionado, aplausos. Parece que -deletedeve ser suportado em sistemas GNU e BSD recentes, enquanto -print0é apenas GNU. Portanto, provavelmente também é mais portátil (embora não deva fazer diferença para o OP).
Inutil)
Pelo menos a localização do OS X tem -print0, mas não está incluída no POSIX.
Lri
5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

também funcionaria no Bash.

Usuário desconhecido
fonte
A expansão da chave exige bash, e o formulário preenchido com zero precisa da versão 4, acredito.
precisa saber é