Os exemplos abaixo muitas vezes usam um recurso chamado Parameter Expansion, presentes no shell Bash. Leia mais sobre esse assunto aqui, aqui e aqui.

1. Renomeando Múltiplos Arquivos Simultaneamente

Demonstro aqui algumas situações que já tive na vida real e os comandos que me permitiram fazer rapidamente algo que levaria muito tempo fazendo manualmente.

Exemplos que mostram o resultado teve o output truncado e com linhas omitidas, restando apenas o suficiente para entender o que aconteceu.

1.1. Renomear extensão para “caixa baixa”, ou “lowercase” - v1

Neste exemplo, renomeamos imagens com extensão .JPG para .jpg.

for img in *.JPG ; do mv -v "$img" "${img%.*}.jpg" ; done
# →  ‘01.JPG’ -> ‘01.jpg’
# →  ‘02.JPG’ -> ‘02.jpg’
#     .......
# →  ‘107.JPG’ -> ‘107.jpg’
#     .......
# →  ‘409.JPG’ -> ‘409.jpg’
#     ....... etc....

Usamos um laço no shell.

for img in *.JPG ; do algum-commando ; done

Com isso, cada imagem com a extensão .JPG (uppercase) é assinada, uma a cada iteração do laço, à variável img.

Para testar, substitua mv -v "$img" "${img%.*}.jpg" por apenas echo "${img%.*}" e assim verá o que acontece.

A expressão "${img%.*}" remove a extensão do arquivo, mas logo em seguida colocamos .jpg manualmente (em lowercase). É esse o “truque” responsável por deixar a extensão em minúsculas.

1.2. Renomear extensão para “caixa baixa”, ou “lowercase” - v2

Imagine centenas de arquivo nesse estilo:

FoO.JPG
baR.JPg
....
Profile.jpG

O seguinte comando vai deixar o nome inteiro do arquivo em lowercase:

for arquivo in *.[jJ][pP][gG] ; do echo "${arquivo,,}" ; done
# →  foo.jpg
# →  bar.jpg
# →  ....
# →  profile.jpg

A parte *.[jJ][pP][gG] diz ao shell para pegar arquivos que comecem com “qualquer coisa”, seguido de um ponto, seguido de “j” ou “J”, “p” ou “P”, “g” ou “G”, ou seja a extensão “jpg” em qualquer combinação de caixa alta e baixa.

Em seguida, a expansão ${arquivo,,} é aplicada para deixar todos os caracteres em $arquivo para caixa baixa.

2. Preencher número com zero.

Imagine uma situação em que temos que renomear arquivos preenchendo certos números com “0” (zero). Por exemplo, “1” vira “01” e “9” fica “09”. Seria um caso onde tivéssemos arquivos com nomes do tipo:

ls -1
pag-2016-10.jpg
pag-2016-11.jpg
....
pag-2016-16.jpg
pag-2016-1.jpg
pag-2016-2.jpg
....
pag-2016-9.jpg

Queremos que, “pag-2016-1.jpg” seja renomeado para “pag-2016-01.jpg” e “pag-2016-2.jpg” para “pag-2016-02.jpg”, etc, até “pag-2016-09.jpg”.

2.1. Usando parameter expansion

for img in pag-2016-[0-9].jpg ; do
    parts=(${img//-/ }) ;
    mv "$img" $( printf %s-%s-0%s.jpg ${parts[0]} ${parts[1]} ${parts[2]%.*} ) ;
done

Neste caso, iteramos sobre arquivos com um nome específico, e que antes do último “.” (ponto) tem algum dígito de zero a nove ([0-9]) seguido de “.jpg”.

Em seguida, fazemos um split no nome do arquivo baseado nos “-”. Nesse ponto, obtemos um array chamado parts, que pode ser representado assim:

parts[0]=pag
parts[1]=2016
parts[2]=1.jpg

A partir daí, o mv recebe como primeiro parâmetro a nome original em $img, e o segundo parâmetro é o resultado de uma combinação de operações dentro de um subshell. Usamos os índices do array parts para “montar” o novo nome do arquivo.

Como parts[2] é 1.jpg, temos que usar outra expansão de parâmetros, no caso ${parts[2]%.*}, que remove o ponto e a extensão, resultando apenas no dígito (justamente o dígito que queremos preencher com um zero à esquerda). É exatamente por isso que tem um 0%s em nossa chamada da função printf.

O resultado seria algo como:

ls -1
pag-2016-01.jpg
pag-2016-02.jpg
....
pag-2016-09.jpg
pag-2016-10.jpg
pag-2016-11.jpg
....
pag-2016-16.jpg

2.2. Usando parameter expansion, printf e sed

for img in pag-2016-[0-9].jpg ; do
    mv "$img" $(printf %s-%d%d.jpg "${img%-*}" "0" $(sed 's/.*\([0-9]\)\.jpg/\1/' <<< $img))
done

Nesta versão, usamos o SED dentro de um subshell para separar o número antes do trecho “.jpg” e passar esse número isolado como o parâmetro para o segundo %d do printf.

2.3. Usando parameter expansion e printf

for img in pag-2016-[0-9].jpg ; do
    parts=(${img//-/ })
    mv "$img" $( printf %s-%s-0%s.jpg ${parts[0]} ${parts[1]} ${parts[2]%.*} )
done

2.4. Usando (perl) rename

Os sistemas Linux geralmente tem instalado um programa chamado rename. Em algumas distribuições, esse comando é na verdade um script Perl, que permite usar todo o poder das expressões regulares Perl. Nesse caso, você pode fazer:

rename -n 's/-(\d)\.jpg/-0\1.jpg/' *.jpg

Esse comando usa a expressão regular /-(\d)\.jpg/, que pega um “-” seguido de um único dígito, seguido de “.jpg”. Na parte da substituição, colocamos o “-” seguido de zero e o número que foi capturado pelo grupo seguido de “.jpg”.

Os caracteres do nome original que não casaram na expressão regular não são tocados. Isso quer dizer que apenas o “-”, o dígito e o “.jpg” do precisam ser colocados na expressão de substituição (a parte entre o segundo e o terceiro “/”).

Por enquanto é isso. May the source be with you!