Um problema com renomeação recursiva é que qualquer que seja o método usado para localizar os arquivos, ele passa todo o caminho para rename , não apenas o nome do arquivo. Isso dificulta a criação de renomeações complexas em pastas aninhadas.
Eu uso a ação find -execdir para resolver esse problema. Se você usar -execdir em vez de -exec , o comando especificado será executado a partir do subdiretório que contém o arquivo correspondente. Portanto, em vez de passar todo o caminho para rename , ele passa apenas ./filename . Isso torna muito mais fácil escrever o regex.
find /the/path -type f \
-name '*.abc' \
-execdir rename 's/\.\/(.+)\.abc$/version1_.abc/' '{}' \;
Em detalhes:
-
-type f significa procurar apenas arquivos, não diretórios
-
-name '*.abc' significa significa apenas corresponder nomes de arquivos que terminam em .abc
- As barras invertidas após
-type e -name são o caractere de continuação da linha de bash. Eu os uso para tornar este exemplo mais legível, mas eles não são necessários na prática.
- No entanto, a barra invertida no final da linha
-execdir é necessária. Ele está lá para expor o ponto-e-vírgula, que finaliza o comando executado por -execdir . Diversão!
Explicação do regex:
-
s/ início da regex
-
\.\/ corresponde ao líder ./que o -execdir passa. Use \ para escapar do. e / metacaracteres
-
(.+) corresponde ao nome do arquivo. Os parênteses capturam a correspondência para uso posterior
-
\.abc escape do ponto, combine o abc
-
$ ancora a correspondência no final da string
-
/ marca o final da parte "correspondência" da expressão regular e o início da parte "substituir"
-
version1_ adicione este texto a todos os nomes de arquivo
-
faz referência ao nome do arquivo existente, porque capturamos com parênteses. Se você usar vários conjuntos de parênteses na parte "match", você pode consultá-los aqui usando $ 2, $ 3, etc.
-
.abc o novo nome do arquivo terminará em .abc. Não há necessidade de escapar do metacaractere ponto aqui na seção "substituir"
-
/ end do regex
Antes
tree --charset=ascii
|-- a_file.abc
|-- Another.abc
|-- Not_this.def
'-- dir1
'-- nested_file.abc
Depois
tree --charset=ascii
|-- version1_a_file.abc
|-- version1_Another.abc
|-- Not_this.def
'-- dir1
'-- version1_nested_file.abc
Dica: a opção rename 's -n é útil. Ele faz uma corrida a seco e mostra a você quais nomes ele mudará, mas não faz alterações.