Vou sugerir três alternativas. Cada um é um simples comando de linha única, mas fornecerei variantes para casos mais complicados, principalmente no caso de os arquivos a serem processados serem misturados com outros arquivos no mesmo diretório.
mmv
Eu usaria o comando mmv
do pacote do mesmo nome :
mmv '*HBO_DPM*' '#1dpm#2'
Note que os argumentos são passados como strings, então a expansão glob não acontece no shell. O comando recebe exatamente dois argumentos e, em seguida, localiza arquivos correspondentes internamente, sem limites rígidos no número de arquivos. Observe também que o comando acima assume que todos os arquivos que correspondem ao primeiro glob devem ser renomeados. Claro que você é livre para ser mais específico:
mmv 'sb_606_HBO_DPM_*' 'sb_606_dpm_#1'
Se você tiver arquivos fora do intervalo de números solicitados no mesmo diretório, talvez seja melhor usar o loop sobre os números fornecidos mais abaixo nesta resposta. No entanto, você também pode usar uma sequência de invocações mmv com padrões adequados:
mmv 'sb_606_HBO_DPM_0089*' 'sb_606_dpm_0089#1' # 0089000-0089999
mmv 'sb_606_HBO_DPM_009*' 'sb_606_dpm_009#1' # 0090000-0099999
mmv 'sb_606_HBO_DPM_01[0-5]*' 'sb_606_dpm_01#1#2' # 0100000-0159999
mmv 'sb_606_HBO_DPM_016[0-2]*' 'sb_606_dpm_016#1#2' # 0160000-0162999
mmv 'sb_606_HBO_DPM_01630[01]?' 'sb_606_dpm_01630#1#2' # 0163000-0163019
mmv 'sb_606_HBO_DPM_016302[0-2]' 'sb_606_dpm_016302#1' # 0163020-0163022
loop over numbers
Se você quiser evitar a instalação de qualquer coisa, ou precisar selecionar por intervalo de números evitando correspondências fora desse intervalo, e você está preparado para aguardar 74.023 invocações de comandos, você pode usar um loop bash simples:
for i in {0089000..0163022}; do mv sb_606_HBO_DPM_$i sb_606_dpm_$i; done
Isso funciona particularmente bem aqui, pois não há lacunas na sequência. Caso contrário, você pode querer verificar se o arquivo de origem realmente existe.
for i in {0089000..0163022}; do
test -e sb_606_HBO_DPM_$i && mv sb_606_HBO_DPM_$i sb_606_dpm_$i
done
Observe que, em contraste com for ((i=89000; i<=163022; ++i))
, a expansão da chave manipula os zeros iniciais desde o lançamento de alguns Bash há alguns anos. Na verdade, uma mudança que solicitei, estou feliz em ver casos de uso para ela.
Outras leituras: Expansão de contraventamentos as páginas de informação do Bash, particularmente a parte sobre {x..y[..incr]}
.
repetição de arquivos
Outra opção seria fazer um loop sobre um glob apropriado, em vez de simplesmente fazer um loop sobre o intervalo inteiro em questão. Algo assim:
for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done
Novamente, essa é uma invocação de mv
por arquivo. E novamente o loop é sobre uma longa lista de elementos, mas a lista inteira não é passada como um argumento para um subprocesso, mas manipulada internamente pelo bash, então o limite não causará problemas.
Outras leituras: Expansão do Parâmetro da Shell nas páginas de informação do Bash, documentando ${parameter/pattern/string}
entre outras.
Se você quisesse restringir o intervalo de números ao que você forneceu, você poderia adicionar um cheque para isso:
for i in sb_606_HBO_DPM_+([0-9]); do
if [[ "${i##*_*(0)}" -ge 89000 ]] && [[ "${i##*_*(0)}" -le 163022 ]]; then
mv "$i" "${i/HBO_DPM/dpm}"
fi
done
Aqui ${i##pattern}
remove o prefixo mais longo que corresponde a pattern
de $i
. O prefixo mais longo é definido como qualquer coisa, então um sublinhado e, em seguida, zero ou mais zeros. O último é escrito como *(0)
, que é um padrão global estendido que depende na extglob
opção definida. Remover zeros à esquerda é importante para tratar o número como base 10 e não como base 8. O +([0-9])
no argumento do loop é outro glob estendido, correspondendo a um ou mais dígitos, caso você possua arquivos que iniciem o mesmo, mas não terminar em um número.