Renomeando vários arquivos de uma só vez no Linux (expressões regulares na prática)

É comum usarmos o comando “mv” que serve tanto para mover quanto para renomear arquivos e diretórios. Mas você sabia que existe um comando “rename” no Linux e mais, você sabe usá-lo para renomear dezenas, centenas ou até mesmo milhares de arquivos de uma só vez?

O comando rename no Linux é pouco conhecido entre os iniciantes, mas é extremamente poderoso se for bem usado (por outro lado extremamente perigoso se usado da forma errada).

Talvez estes parenteses expliquem o porque de não ser tão popular, mas o “rm -rf” é muito mais perigoso e ainda assim é ensinado a iniciantes, então por que não ensinar o comando “rename” também, seguido das devidas recomendações?

O comando rename vem no pacote de mesmo nome e em algumas distribuições é preciso instalá-lo a parte. Nada que um “apt”, “yum” “dnf” etc não resolvam.

Além da instalação, outro prérequisito para usá-lo é conhecer um mínimo de REGEX. Sim, expressões regulares. Elas podem ser assustadoras as vezes, mas são elas que trazem todo o poder ao comando rename.

O básico do comando rename

A sintaxe do comando rename é bem simples, como segue:

rename [opções] 'ações regex' arquivos

Após o comando rename podemos usar algumas “opções” para modificar a forma como ele funciona, mas de todas as opções disponíveis a que mais usamos é a opção “-n” ou “–nono” que indica ao rename para não fazer nada. Esta opção é útil para simularmos o que a expressão criada irá fazer, sem realmente renomear os arquivos.

Esta então é a dica de ouro para que você não faça besteira. Sempre que tiver dúvidas sobre o que a sua expressão regular vai causar nos arquivos, ative a opção “-n”. Se o resultado for o esperado, execute o comando novamente sem esta a opção para que seus arquivos sejam modificados.

Ações regex” são as ações que vamos executar com regex para modificar os nomes dos arquivos. São apenas duas ações que você precisa decorar, ou deixar anotado em algum lugar para consulta futura, como será visto a seguir.

Arquivos” é a lista de arquivos que desejamos alterar os nomes, em geral usamos caracteres curingas para indicar um conjunto grande arquivos como “*” ou “*.txt” etc.

Antes de termos alguns exemplos, vejamos como funcionam alguns comandos básicos com regex.

Ações básicas com regex para renomear arquivos

As duas principais ações com expressões regulares que precisamos saber para renomear arquivos são:

1 – Substituição de strings: “s/STRING ORIGINAL/NOVA STRING/

O “s” inicial é o comando que indica que queremos substituir uma string por outra. Enquanto as próprias strings ou expressões ficam entre as “/”.

Nós inclusive podemos usar esta mesma ação para remover a string original, bastando apenas não informar a nova string, que indicaria substituir por “nada”.

2 – Substituição de caracteres: “y/CARACTER ORIGINAL/NOVO CARACTER/

O “y” inicial é o comando de substituição e observe que o seu uso é similar ao “s”. A diferença é que enquanto um substitui de toda uma sequência, o outro substitui apenas um caractere.

Estes dois comandos são mais do que suficientes para renomearmos a maioria dos conjuntos de arquivos.

Expressões regulares (REGEX)

Nas ações anteriores nós podemos usar strings, caracteres ou expressões (“códigos” que representam um conjunto de caracteres).

Os códigos principais que podemos usar são:

  • [a-z] – Conjunto de letras minúsculas
  • [A-Z] – Conjunto de letras maiúsculas
  • \w – Conjunto de todas as letras
  • [0-9] – Conjunto dos algarismos (pode ser \d também)
  • . – Um caracter qualquer
  • ^ – Posicionado no início (também pode significar negado, se estiver dentro de um conjunto)
  • | – “ou” Pode ser uma opção ou a outra
  • $ – Posicionado no final
  • ? – Pode existir 0 ou 1 ocorrência
  • * – Pode existir 0 ou várias ocorrências
  • + – Pode existir 1 ou várias ocorrências
  • {n,m} – Pode existir entre “n” e “m” ocorrências
  • (expr) – “Lembre-se deixe conjunto”
  • \1, \2, \3 etc – O conteúdo do conjunto que pedi para lembrar

Como o texto é sobre renomear arquivos e não sobre regex, nós veremos alguns destes símbolos em uso renomeando arquivos. Mas sugiro um leitura mais detalhada sobre REGEX para quem interessar sobre o assunto.

Usando o comando rename na prática

Vamos tomar como exemplo o conjunto de arquivos abaixo, onde aplicaremos as expressões acima junto com o comando rename para modificar seus nomes.

ls -1
APP.PY3
OLD.ENV
PROVIDER.PY3.BAK
README.MD
rel_1.py3
rel_2.py3
rel3.py3
rel-4.py3
RUN.PY3
VIEW.PY3.BAK

Lembrando que ao fazer na prática recomendo o uso do argumento “-n” para testar se a sua expressão afetará apenas os arquivos desejados.

Colocando todos os nomes de arquivos em minúsculas

Neste primeiro exemplo, vamos usar o seguinte comando:

rename -n "y/[A-Z]/[a-z]/" *

Observe que foi usado o argumento “-n” então ao invés de renomear de fato, o comando rename apenas exibirá quais arquivos serão afetados e qual seria o resultado.

Note ainda que foi usada a ação “y” (substituir caracteres) para substituir o conjunto de maiúsculas pelo conjunto de minúsculas, em todos os arquivos que estiverem na pasta atual.

Considerando a lista de arquivos que tomamos como exemplo, o resultado será o seguinte:

rename -n "y/[A-Z]/[a-z]/" *
rename(APP.PY3, app.py3)
rename(OLD.ENV, old.env)
rename(PROVIDER.PY3.BAK, provider.py3.bak)
rename(README.MD, readme.md)
rename(RUN.PY3, run.py3)
rename(VIEW.PY3.BAK, view.py3.bak)

A exibição dos resultados tem um “jeitão” especial. Ele exibe a palavra “rename” seguida do antes e depois da ação, entre parênteses, ou seja “APP.PY3” se tornará “app.py3”; “OLD.ENV” muda para “old.env” etc.

Se realmente é este o resultado esperado basta repetir o comando, mas desta vez sem o uso do argumento “-n”, para que os arquivos sejam efetivamente renomeados.

Nada será exibido na tela (a menos que você troque o “-n” pelo “-v”) mas ao listar os arquivos teremos a listagem agora como segue:

ls -1
app.py3
old.env
provider.py3.bak
readme.md
rel_1.py3
rel_2.py3
rel3.py3
rel-4.py3
run.py3
view.py3.bak

A partir de então todos os arquivos possuem seus nomes em letras minúsculas.

Removendo ou trocando a extensão dos arquivos

Nesta listagem nós temos dois arquivos de backup (*.bak) e eu quero torna-los arquivos “.py3” novamente, removendo a extensão dupla “.bak”, da seguinte forma:

rename 's/.bak//' *.bak

Usando a ação “s” nós substituímos uma string inteira (e não os caracteres isolados, como foi o caso da ação “y”). Neste caso, a substituição foi da string “.bak” por “nada” e o resultado foi o que segue:

ls -1
app.py3
old.env
provider.py3
readme.md
rel_1.py3
rel_2.py3
rel3.py3
rel-4.py3
run.py3
view.py3

Se precisarmos trocar uma extensão por outra, então para complementar o exemplo anterior, observe este aqui, em que trocamos a extensão “.py3” por apenas “.py”.

rename -n 's/.py3/.py/' *.py3
rename(app.py3, app.py)
rename(provider.py3, provider.py)
rename(rel_1.py3, rel_1.py)
rename(rel_2.py3, rel_2.py)
rename(rel3.py3, rel3.py)
rename(rel-4.py3, rel-4.py)
rename(run.py3, run.py)
rename(view.py3, view.py)

Tal como no exemplo anterior, foi usada a ação “s” para substituir strings, porém desta vez informamos a string original e a nova string.

Aplicando as alterações (removendo o “-n”) esta será a nossa listagem agora:

rename 's/py3/py/' *.py3 ; ls -1
app.py
old.env
provider.py
readme.md
rel_1.py
rel_2.py
rel3.py
rel-4.py
run.py
view.py

Padronizando os nomes

Nós temos alguns arquivos que começam com “rel” (quatro, na verdade) porém seus nomes estão desorganizados. Vamos tentar padronizá-los de algumas formas:

Opção 1 – Removendo o hífen (-) e o underscore (_):

rename -n 's/_|-//' rel*
rename(rel_1.py, rel1.py)
rename(rel_2.py, rel2.py)
rename(rel-4.py, rel4.py)

Note ali que, embora queira lidar com apenas um caractere, eu usei a ação “s” porque a “y” requer obrigatoriamente que informe o caractere substituto, mas neste caso como estamos removendo, ele não existe.

Perceba ainda o uso do operador “|” (ou) que indica que se encontra “_” OU “-” a substituição deverá ocorrer. Eu poderia trocar o “_|-” por “[_-]” que funcionaria da mesma forma.

Se executarmos o comando rename sem o “-n” passaríamos a ter 4 arquivos “rel?.py”, onde a “?” aqui corresponde aos seus respectivos números, mas ao invés de aplicarmos, vamos ver um outro exemplo.

Opção 2 – Deixando apenas os números

rename -n 's/rel[_-]?//' rel*
rename(rel_1.py, 1.py)
rename(rel_2.py, 2.py)
rename(rel3.py, 3.py)
rename(rel-4.py, 4.py)

Esta é um pouco mais sofisticadacomplicada. Nós estamos removendo (substituindo por nada) tudo que tenha a string “rel” seguida de “_” ou de “-“. A “?” que vem a seguir indica que estes caracteres (_ ou -) podem ou não estar lá (0 ou 1 ocorrência), ou seja, esta expressão casaria com “rel”, “rel_” e “rel-” que em todos os casos seriam removidos, sobrando apenas o número.

Opção 3 – Deixando os nomes mais organizados

rename -n 's/rel[-_]?([0-9])/relatorio@\1/' rel*
rename(rel_1.py, relatorio@1.py)
rename(rel_2.py, relatorio@2.py)
rename(rel3.py, relatorio@3.py)
rename(rel-4.py, relatorio@4.py)

Esta opção é bem mais sofisticada que a anterior, porém igualmente simples de entender se pegarmos cada parte isolada da expressão.

Perceba que começamos a expressão igual a anterior (com “rel[_-]?”). O nome deve começar com “rel”, seguido ou não dos caracteres “-” ou “_”, porém em seguida está a primeira diferença. Deve possuir um dígito entre 0 e 9, representado por [0-9].

Perceba ainda que nós pusemos esta classe/conjunto entre “()”. Esta é a segunda diferença e serve para “lembrar” o conteúdo encontrado neste pedaço da expressão. Ou seja, como este pedaço vai combinar apenas com os números de 0 a 9, o rename vai lembrar os números que encontrar ali para cada arquivo.

E para que ele vai lembrar este número? Para usarmos na nossa terceira diferença. Nós estamos substituindo tudo que combinar com a expressão regular, pela string “relatorio@” acompanhada do número que foi “lembrado” da seção anterior.

Aplicando esta última alteração (removendo o “-n”) a nossa listagem deve estar como segue:

ls -1
app.py
old.env
provider.py
readme.md
relatorio@1.py
relatorio@2.py
relatorio@3.py
relatorio@4.py
run.py
view.py

Finalização

Estes foram apenas alguns exemplo básicos de uso do comando rename e de expressões regulares.

Há muito a se fazer apenas com estes dois recursos mas o que está aqui é o começo para quem quer se tornar um bom administrador de sistemas e sentir-se seguro em operar seu ambiente a partir da linha de comandos.

Junte a estes recursos o uso de loops, filtros com grep, sed, awk entre outros e logo você vai se irritar com o uso de gerenciadores de arquivos gráficos que são extremamente limitados.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.