Eu tinha um grupo de arquivos que gostaria de renomear de forma consistente, os arquivos têm nomes como
"System-Log-01-01-2009-NODATA.txt"
"Something-Log-01-01-2009-NODATA.txt"
E eu os queria em letras minúsculas, aaaammdd, extensão .log
"system.20090101.log"
"something.20090101.log"
Eu costumava escrever scripts Perl para fazer isso, até descobrir o comando rename.
Ele aceita uma regex Perl para fazer a renomeação:
para isso, basta digitar dois comandos:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *
rename 'y/A-Z/a-z/' *.log
Para algumas distros, porém, rename
não tem esta funcionalidade (veja sua página de manual), e você pode ter que instalar Perl-rename
ou prename
.
Como não tenho um comando de renomeação, estou contando com o seguinte:
for myfile in /my/folder/*; do
target=$(echo $myfile|sed -e 's/foo/bar/g')
mv "$myfile" "$target"
done
rename
util não é muito "padrão". Cada distro vem com uma ferramenta rename
diferente. Por exemplo, aqui no Gentoo, rename
é de sys-apps/util-linux
pacote e não suporta regex.
Hamish Downer sugeriu mmv
, parece útil, especialmente para uso dentro de scripts.
Por outro lado, para o caso geral, você pode querer renomearutils . Ele possui os comandos qmv
e qcp
, que abrirão um editor de texto de sua escolha (minha preferência: Vim) e permitirá que você edite os nomes dos arquivos de destino lá. Depois de salvar e fechar o editor, qmv
/qcp
fará toda a renomeação.
Ambos mmv
e qmv
são inteligentes o suficiente para renomear arquivos na ordem correta e também para detectar renomeações circulares, e farão automaticamente um arquivo temporário se necessário.
mmv é um utilitário linux padrão para mover/renomear vários arquivos. Ele está disponível nos repositórios para a maioria das distribuições. Para o seu exemplo acima, você poderia fazer:
mmv *-Log-*-*-*-NODATA.txt #l1.#4#3#2.log
Para obter mais informações, leia este artigo debaday ou a página do manual .
Para ser justo:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *.txt
dá esta saída:
Use of uninitialized value $4 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $3 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $2 in regexp compilation at (eval 1) line 1.
Mas:
rename -n 's/(\w+)-\w+-(\d{2})-(\d{2})-(\d{4})-NODATA\.txt$/$1.$4$3$2\.log/' *.txt && rename 'y/A-Z/a-z/' System.20090101.log
dá a saída certa:
System-Log-01-01-2009-NODATA.txt renamed as System.20090101.log
System.20090101.log renamed as system.20090101.log
substituindo o interruptor {-n} por {-v}
Criei um pequeno script bash para fazer isso:
#!/bin/bash
for f in `ls /path/to/folder`; do
# Create new filename from the old one
# This example replaces A (upper case) with a (lower case)
new_file=`echo "$new_file" | tr A a`
# Rename the file
mv "$f" "$new_file"
done