Renomeando Vários Arquivos Simultaneamente
Colaboração: Thiago Cesar Vieira
Data de Publicação: 01 de abril de 2010
Sabe aquela boa funcionalidade do MS Windows para renomear arquivos simultaneamente? Você seleciona alguns arquivos no gerenciador de arquivos Windows Explorer, clica com o botão direito do mouse, então Renomear, escreve um nome e os arquivos são magicamente nomeados seguindo uma ordem de numeração!
Sente falta desse recurso no seu Linux?
Esse script tem a mesma função. Mas, ainda não no Nautilus (gerenciador de arquivos do GNOME)... por enquanto apenas no terminal!
Como usar o script
As câmeras digitais armazenam arquivos com nomes sequenciais, que fazem pouco sentido para os usuários, por exemplo: DSC74201.JPG
, DSC74202.JPG
.
Suponhamos que queiramos renomeá-las de acordo com um tema. Por exemplo, para renomear todas as fotos que tirar na praia, use o script da seguinte forma:
$ renaming_files.sh "passeio_praia" /home/eu/fotos/
Os arquivos do diretório /home/eu/fotos/
serão renomeados. Veja na tabela abaixo o resultado.
Antes | Depois |
---|---|
DSC74218.JPG |
passeio_praia (1).JPG |
DSC74223.JPG |
passeio_praia (2).JPG |
DSC74247.JPG |
passeio_praia (3).JPG |
ATENÇÃO: todos os arquivos do diretório serão renomeados! Se você tem documentos, fotos e vídeos no mesmo lugar, provavelmente não queira renomeá-los da mesma forma. Assim, é interessante renomear por grupos de arquivos.
Para trabalhar com uma lista de arquivos, basta apenas informar os arquivos a renomear. Por exemplo:
$ renaming_files.sh "passeio_praia" DSC74218.JPG DSC74223.JPG
Isso faz com que somente os arquivos DSC74218.JPG
e DSC74223.JPG
sejam renomeados para passeio_praia (1).JPG
e passeio_praia (2).JPG
, respectivamente.
Aos usuários inexperientes: tenha muito cuidado ao usar comando que renomeiam arquivos em lotes. O resultado talvez seja irreversível. Então, assegure-se do que está fazendo.
Script
Segue abaixo o Bash script.
Por favor, opine caso não tenha gostado de uma linha de código, por motivos de performance, perigo ao executar tal comando, ilegibilidade ou qualquer outro que ache conveniente.
Gostaria de aprender como se faz corretamente.
#!/bin/bash # # Rename a list of files or all files in a directory. # File: renaming_files.sh # Author: Thiago Cesar Vieira # Date: 2010-02-27 # Usage: renaming_files.sh "{new file name}" {list of files or directory} # Note: file extension will NOT be changed. Only files in that directory will be renamed, NOT enter in subdirectories. # Todo: Try to reorder the list of files before changing name. # # For example: # Running 'renaming_files.sh "my travel" /home/me/pictures/' # Files in the /home/me/pictures/ directory will be renamed to: 'my travel (1).jpg', 'my travel (2).jpg', 'my travel (3).PNG', etc. # # Running 'renaming_files.sh "workshop" 2010-02-08.doc 2010-02-25.doc' # Rename '2010-02-08.doc' and '2010-02-25.doc' to: 'workshop (1).doc' and 'workshop (2).doc'. helpfunc() { echo $'\n'"Rename a list of files or all files in a directory." echo "Usage: $0 {\"new file name\"} {list of files or directory}" echo "For example:" echo " Running '$0 \"my travel\" /home/me/pictures/'" echo " Files in the /home/me/pictures/ directory will be renamed to: 'my travel (1).jpg', 'my travel (2).jpg', 'my travel (3).PNG', etc." echo echo " Running '$0 \"workshop\" 2010-02-08.doc 2010-02-25.doc'" echo " Rename '2010-02-08.doc' and '2010-02-25.doc' to: 'workshop (1).doc' and 'workshop (2).doc'." echo $'\a' # alert (bell) exit 1 } # new file names NEW_FILENAME="$1" # reassigns the positional parameters, shifting them to the left one notch. $1 <- $2, $2 <- $3 shift # directory or a file DIRECTORY_OR_FILE="$1" # Bash scripts use $IFS (Internal Field Separator) variable to determine what are field separators. By default $IFS is set to the space character. Changing to new line. # setting $IFS: now it will only split on newlines, not spaces IFS=$'\n' # checking if the pattern is not empty if [ "$NEW_FILENAME" != "" ] ; then # checking if trying to renames files in directory or a list of files # checking if directory exist if [ -d "$DIRECTORY_OR_FILE" ] ; then echo "Renaming all files in '$DIRECTORY_OR_FILE'..." # get all files in the directory (ignore sub-directories) ORIGINAL_FILES=$(find $DIRECTORY_OR_FILE -maxdepth 1 -type f) # checking if file exist elif [ -f "$DIRECTORY_OR_FILE" ] ; then ORIGINAL_FILES=$* echo "Renaming files:" echo "$ORIGINAL_FILES" else echo "Fatal error. No input found. Enter a directory of a list of files to rename." helpfunc fi # start counter (used to rename files sequentially intCounter=1 # loop for all files for ORIGINAL_FILE in $ORIGINAL_FILES ; do # checking if file really exist. Note, -e test also return true if argument is a directory! if [ -f "$ORIGINAL_FILE" ] ; then # get the file-extension FILE_EXTENSION="${ORIGINAL_FILE##*.}" # searching for the last dot # set the new file-name NEW_FILE="$(dirname $ORIGINAL_FILE)/$NEW_FILENAME ($intCounter).$FILE_EXTENSION" # checking if file already exist if [ ! -e "$NEW_FILE" ] ; then # renaming the file mv --verbose $ORIGINAL_FILE $NEW_FILE # increment the counter let "intCounter+=1" else echo "Warning. File '$NEW_FILE' already exists. NOT renaming '$ORIGINAL_FILE'." fi else echo "Warning. File not exist '$ORIGINAL_FILE'. Ignoring..." fi done else echo "Fatal error. File-name is empty." helpfunc fi exit 0
Referências
Existem muitas soluções para esse problema. Como não encontrei nenhuma que satisfazia as minhas necessidades, escrevi um script.
- Solução em apenas 1 linha de código!
- http://www.slackbr.org/forum/viewtopic.php?f=201&t=16354
- Script similar, mas com alguns problemas: não renomeia arquivos com espaços no nome, em meus testes o contador sempre iniciou do 1 quando renomeava mais de um arquivo
- http://www.vivaolinux.com.br/script/Script-para-renomear-arquivos/
- Script similar, mas com alguns problemas: não renomeia arquivos com espaços no nome, não permite espaços no novo nome, renomeia diretórios, precisa ser rodado dentro do diretório com os arquivos
- http://www.dicas-l.com.br/dicas-l/20080301.php
- Script para mudar extensão de arquivos, mas com alguns problemas: é estático, não renomeia arquivos com espaços no nome (nessas condições, renomeia outros arquivos fora do padrão especificado), precisa ser rodado dentro do diretório com os arquivos, retorna erro caso tenha diretório com ".txt" no nome, processa arquivos dentro de diretório com ".txt" no nome
- http://www.dicas-l.com.br/dicas-l/20080221.php
- Script para mudar extensão de arquivos, mas com alguns problemas: é estático, não renomeia arquivos com espaços no nome (nessas condições, renomeia outros arquivos fora do padrão especificado), precisa ser rodado dentro do diretório com os arquivos, retorna erro caso tenha diretório com ".txt" no nome, processa arquivos dentro de diretório com ".txt" no nome, arquivos com mais de um ponto separador não são renomeados corretamente
- http://www.dicas-l.com.br/dicas-l/20080219.php
- Script para alterar nomes de arquivos
- http://www.dicas-l.com.br/dicas-l/20050305.php
- Comando rename:
- http://linux.about.com/library/cmd/blcmdl1_rename.htm