Localiza e substitui string em uma lista de nomes de arquivos

2

Eu tenho alguns arquivos assim (no Mac OS X):

product-103-footer.tpl
product-103-header.tpl
product-103.tpl

Eu quero substituir '103' em todos os nomes de arquivos por alguma outra coisa usando grep e sed, ou algo assim.

Como faço isso?

Aqui está uma pseudo linha de comando do que eu quero alcançar

find . /[103] | grep 103 | sed s/103/104/

Espero que isso faça sentido!

EDITAR:

Aproximando-se:

find . -name 'product-103*' -print | sed 's/103/104/g'
    
por josef.van.niekerk 26.03.2013 / 14:35

3 respostas

8

Você pode usar a opção find de exec para (recursivamente) fazer um loop sobre todos os arquivos e, em seguida, usar substituições simples de string:

find . -type f -name "product-103*" \
-exec sh -c 'echo mv "$0" "${0/103/104}"' '{}' \;

Remova o echo quando tiver certeza de que isso é o que você deseja.

Basicamente, o que exec faz é substituir o nome de cada arquivo encontrado em {} , que é passado como um argumento para sh -c . Este argumento está disponível como $0 , portanto, o nome do arquivo. Usamos esse argumento $0 em uma chamada mv , em que o segundo argumento é o novo nome de arquivo. Aqui, 103 é substituído por 104. Observe que são necessárias aspas duplas para manipular corretamente os espaços em branco nos nomes dos arquivos.

Consulte Manipulação de strings no Guia de scripts do Bash.

Com zmv do zsh (no OS X até /bin/zsh ):

autoload -U zmv
zmv -Wn '*103*' '*104*'

Remova a opção -n quando isso acontecer.

    
por 26.03.2013 / 14:59
2

Perl é melhor para isso.

find . -name 'product-103*' | perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

O seguinte trecho de código

perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

será eventualmente expandido para

while (<>) {
    chomp;
    ($new=$_) =~ s/103/104/;
    rename $_, $new;
}

O operador <> irá obter cada nome de arquivo com um '\ n' no final e salvá-lo em $ _, então chomp irá cortar o '\ n' off. Em seguida, a variável $new obtém o nome do arquivo antigo de $_ e substitui 103 a 104. Por fim, rename apenas renomeia o arquivo em questão para seu novo nome. Para mais detalhes sobre a opção -n -l -e, consulte a parte perlrun do perldoc.

    
por 26.03.2013 / 15:01
2
for f in product-103*; do mv "$f" "${f/103/104}"; done
    
por 26.03.2013 / 17:56