Como 'rm' ou 'mv' um intervalo de arquivos como file01.txt, file02.txt… file85.txt

22

Suponha que eu tenha vários arquivos nomeados desta forma:

file01.txt file02.txt file03.txt ... file20.txt

e eu quero executar um comando em um intervalo desses arquivos.

Eu sei que se quiser 'rm' de 'file05.txt' para 'file09.txt' eu posso fazer:

rm file0[5-9].txt

mas como posso 'rm' um intervalo de arquivo08.txt para arquivo13.txt? Eu tentei esse código

rm file[08-13].txt

e isso não funciona. Eu poderia executar este comando:

rm file0[89].txt file1[0-3].txt

mas gostaria de saber se posso fazer isso com apenas mais um argumento refinado para 'rm' se for possível.

    
por Cesare Fusari 07.08.2016 / 10:05

2 respostas

37

Você precisa usar a expansão de chave de bash :

rm file{08..13}.txt

Isso removerá os arquivos file08 para file13 e mostrará uma mensagem de erro se algum arquivo estiver faltando.

Defina o intervalo para atender sua necessidade.

O problema com o operador de globbing [] é que ele trata cada caractere / dígito dentro dele como um único token e, portanto, suporta apenas a declaração de intervalo usando dígitos únicos.

Se você insistir em usar [] , poderá usar esse padrão bastante feio para corresponder file08 a file13 :

rm file0[8-9].txt file1[0-3].txt
    
por heemayl 07.08.2016 / 10:06
2

Alguns shells, como o /bin/sh do padrão do Ubuntu (que é dash ) ou mksh não possuem expansão de chave, ou no caso de ksh - a expansão de chave não pode usar zeros:

$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13

Nesses casos, podemos usar printf para formatar a parte numérica do nome do arquivo e usar um loop while para implementar o comportamento de loop de c-like (nota para substituir echo por rm ou o que for você quer):

$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

E isso é bastante portátil - funciona com dash , ksh , mksh e também bash . No caso de ksh e bash , também podemos usar c-style for loop syntax (but not in case of mksh or dash '):

$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'             
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Observe que, no caso de bash , printf suporta impressão para variável e, portanto, podemos fazer printf -v num "%.2d" "$i" em vez de usar a substituição de comando.

    
por Sergiy Kolodyazhnyy 31.10.2017 / 20:52