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

23

Suponha que eu tenha um monte de arquivos nomeados desta maneira:

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

e quero executar um comando em um intervalo desses arquivos.

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

rm file0[5-9].txt

mas como posso 'rm' um intervalo de file08.txt a file13.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.


fonte
Uma pergunta quase idêntica foi respondida aqui: stackoverflow.com/questions/25049411/…
arielf 12/08/16

Respostas:

38

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

rm file{08..13}.txt

Isso removerá os arquivos file08para file13, mostrará uma mensagem de erro se algum arquivo estiver faltando.

Defina o intervalo para atender às suas necessidades.


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

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

rm file0[8-9].txt file1[0-3].txt
heemail
fonte
5
expansão de cinta também é útil com vírgulas, como para mv foo.{txt,md}oucp foo.txt{,.bak}
Kos
2

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

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

Nesses casos, pode-se fazer uso de printfformatar a parte do número do nome do arquivo, e usar um loop while para implementar c-like para o comportamento loop (nota para substituir echocom rmou o que quiser):

$ 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 - trabalha com dash, ksh, mksh, também bash. No caso de kshe bashtambém podemos usar c-style for loop syntax (but not in case ofmksh ordash`):

$ 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 bashcaso, printfsuporta impressão em variável e, portanto, poderíamos fazer isso em printf -v num "%.2d" "$i"vez de usar a substituição de comando.

Sergiy Kolodyazhnyy
fonte