Como renomear múltiplos arquivos substituindo word no nome do arquivo?

36

Substitua o ACDC por AC-DC

Por exemplo, temos esses arquivos

ACDC - Rock N' Roll Ain't Noise Pollution.xxx

ACDC - Rocker.xxx

ACDC - Shoot To Thrill.xxx

Eu quero que eles se tornem:

AC-DC - Rock N' Roll Ain't Noise Pollution.xxx

AC-DC - Rocker.xxx

AC-DC - Shoot To Thrill.xxx

Eu sei que sed ou awk é usado para esta operação. Eu não posso google nada, então eu estou pedindo sua ajuda =) Você poderia por favor fornecer o comando shell completo de trabalho para esta tarefa?

Feedback: Solução para usuários do OSX

    
por holms 30.01.2011 / 09:00

6 respostas

45
rename 's/ACDC/AC-DC/' *.xxx

de man rename

DESCRIPTION
       "rename" renames the filenames supplied according to the rule specified as the 
first argument.  The perlexpr argument is a Perl expression which is expected to modify the 
$_ string in Perl for at least some of the filenames specified.  If a given filename is not 
modified by the expression, it will not be renamed.  If no filenames are given on
           the command line, filenames will be read via standard input.

Por exemplo, para renomear todos os arquivos que combinam "* .bak" para remover a extensão, você pode dizer

rename 's/\.bak$//' *.bak

Para traduzir nomes em maiúsculas para menores, você usaria

rename 'y/A-Z/a-z/' *
    
por 30.01.2011 / 09:11
13

Esta resposta contém as partes boas de todas as outras respostas, deixando de fora tal heresia como ls | while read .

Diretório atual:

for file in ACDC*.xxx; do
    mv "$file" "${file//ACDC/AC-DC}"
done

Incluindo subdiretórios:

find . -type f -name "ACDC*" -print0 | while read -r -d '' file; do
    mv "$file" "${file//ACDC/AC-DC}"
done

Caracteres newline são realmente improváveis de estarem em nomes de arquivos, então isso pode ser mais simples enquanto ainda trabalha com nomes contendo espaços:

find . -type f -name "ACDC*" | while read -r file; do
    mv "$file" "${file//ACDC/AC-DC}"
done
    
por 30.01.2011 / 10:03
9

Para usar a versão util-linux do rename que o Phil referenciou (no Ubuntu, chama-se rename.ul ):

rename ACDC AC-DC ACDC*

ou

rename.ul ACDC AC-DC ACDC*
    
por 30.01.2011 / 12:14
4

Usando o shell bash

find . -type f -name "ACDC*" -print0 | while read -d $'
find . -type f -name "ACDC*" -print0 | while read -d $'%pre%' f
do
   new='echo "$f" | sed -e "s/ACDC/AC-DC/"'
   mv "$f" "$new"
done
' f do new='echo "$f" | sed -e "s/ACDC/AC-DC/"' mv "$f" "$new" done

Nota: usar find processará o diretório atual e os diretórios abaixo.

    
por 30.01.2011 / 09:24
1

Depende do seu shell. Em zsh, eu faria isso:

for file in ACDC*.xxx; do
    mv "$file" "$(echo $file | sed -e 's/ACDC/AC-DC/')"
done

Provavelmente não é a melhor solução, mas funciona.

    
por 30.01.2011 / 09:09
1

Usando o bash:

ls *.xxx | while read fn; do
    mv "${fn}" "${fn/ACDC/AC-DC}";
done

Se você tiver o programa rename instalado:

rename 's/ACDC/AC-DC/' *.xxx
    
por 30.01.2011 / 09:16