Vou sugerir três alternativas. Cada um é um comando simples 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 com o mesmo nome :
mmv '*HBO_DPM*' '#1dpm#2'
Observe que os argumentos são passados como seqüências de caracteres, para que a expansão glob não ocorra no shell. O comando recebe exatamente dois argumentos e localiza os arquivos correspondentes internamente, sem limites rígidos no número de arquivos. Observe também que o comando acima pressupõe 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 solicitado no mesmo diretório, pode ser melhor usar os números de loop over dados 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 sobre números
Se você deseja evitar a instalação de qualquer coisa ou precisa selecionar por intervalo de números, evitando correspondências fora desse intervalo, e está preparado para aguardar 74.023 chamadas de comando, 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, convém 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 cinta, lida com zeros à esquerda, pois alguns Bash lançam alguns anos atrás. Na verdade, uma alteração solicitada, por isso estou feliz em ver casos de uso.
Leitura adicional: Expanda a chave nas páginas de informações do Bash, principalmente na parte sobre {x..y[..incr]}
.
loop sobre arquivos
Outra opção seria fazer um loop sobre um globo adequado, em vez de apenas fazer um loop no intervalo inteiro em questão. Algo assim:
for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done
Novamente, essa é uma mv
chamada por arquivo. E novamente o loop contém uma longa lista de elementos, mas a lista inteira não é passada como argumento para um subprocesso, mas manipulada internamente pelo bash, para que o limite não cause problemas.
Leitura adicional: Expansão dos parâmetros do shell nas páginas de informações do Bash, documentando ${parameter/pattern/string}
entre outros.
Se você deseja restringir o intervalo de números ao que você forneceu, adicione uma verificação 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 a mais longa correspondência prefixo pattern
de $i
. Esse prefixo mais longo é definido como qualquer coisa, depois um sublinhado e zero ou mais zeros. O último é escrito como *(0)
um padrão glob extendido que depende da extglob
opção que está sendo configurada. A remoção de zeros à esquerda é importante para tratar o número como base 10 e não 8. O +([0-9])
argumento no loop é outro globo estendido, que corresponde a um ou mais dígitos, apenas no caso de você ter arquivos que iniciam o mesmo, mas não terminam em um número.
ARG_MAX
limite do shell . Como essa pergunta solicita explicitamente uma solução de linha de comando, soluções GUI (possivelmente iguais), como na outra pergunta, também não coincidem.