Renomear vários arquivos usando script Bash

Desejo renomear vários arquivos no mesmo diretório usando script Bash. Os nomes dos arquivos são os seguintes:

file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p 

Desejo renomear para o seguinte formato:

file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p 

Eu estava lendo sobre o comando renomear e tento fazer dessa forma, mas não adianta nada, acho que tenho dúvidas sobre a sintaxe. Então eu li que você pode fazer um loop usando o comando mv da seguinte maneira:

for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done 

Mas não consigo renomear os arquivos. O que estou fazendo de errado?

Comentários

  • possível duplicata de Como posso renomear muitos de arquivos usando um regex?
  • Você pode ' t ter uma expressão padrão no lado direito de uma expressão de substituição de expansão de parâmetro. O que você esperava estar onde * está?
  • @Kiwy Essa pergunta é sobre como remover uma parte do nome do arquivo. Logo, duvido muito, duplique.
  • Da próxima vez, descreva as alterações no nome do arquivo que deseja fazer (tive que olhar para isso por um tempo antes de ver as diferenças e semelhanças). Exemplos são bons, mas uma descrição e exemplos é ainda melhor.

Resposta

Você estava certo ao considerar renomear primeiro. A sintaxe é um pouco estranha se você não está acostumado a regexes, mas é de longe o caminho mais rápido / mais curto depois que você sabe o que está fazendo:

rename "s/\d{4}/2503/" file* 

Isso simplesmente corresponde aos primeiros 4 números e os troca pelos que você especificou.

E um equipamento de teste (-vn significa ser prolixo, mas não faça qualquer coisa) usando seus nomes de arquivo:

$ rename "s/\d{4}/2503/" file* -vn file0901201437404.p renamed as file2503201437404.p file0901201438761.p renamed as file2503201438761.p file1003201410069.p renamed as file2503201410069.p file2602201409853.p renamed as file2503201409853.p file2602201410180.p renamed as file2503201410180.p 

Comentários

  • Observação que esta é a renomeação Perl no Debian e derivados (Ubuntu, Mint, …). Em outras distribuições do Linux, rename é uma ferramenta de renomeação de arquivo completamente diferente (que o Debian fornece como rename.ul).
  • Se você não tiver essa ferramenta distributiva, veja a resposta de @Michael Campbell Acho que todo padrão de substituição distributiva rename como o debian fez.

Resposta

Isso deve funcionar:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done 

Ele substitui a string entre o 4º e o 12º caractere por “25032014”.

Comentários

  • isso for f in file*; do mv $f ${f/${f:4:4}/2503}; done também funciona.
  • Isso ' é bom. Se você deseja apenas fazer uma substituição regular de palavra por palavra, funciona como o sed. por exemplo. for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
  • @Eric – Postei sua resposta como alternativa porque acho ' mais clara e elegante . Se você também quiser postá-lo como uma resposta – eu ' excluirei o meu. Obrigado!
  • Por que aspas duplas ausentes ?
  • Isso me deu um erro: " mv: target ' FILE_NAME ' não é um diretório "

Resposta

esta é realmente a resposta de @Eric “acima – mas é uma resposta elegante, então Estou publicando-a novamente como uma resposta adequada para chamar mais atenção para ela.

for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done 

Resposta

ptrn="file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p" path=/dir ( set -- "${path}/"${ptrn} ; for f ; do { echo "mv ${path}/${f} \ ${path}/file25032014${f#2014}" } ; done ) 

Isso deve funcionar. Observação – não tenho o hábito de entregar comandos de mv em massa – conforme está escrito,” é apenas um eco. Você ” terá que resolver isso antes de “funcionar.

Resposta

Uma maneira nativa simples de fazer isso sem loop, com travessia de diretório :

find -type f | xargs -I {} mv {} {}.txt 

Ele renomeará todos arquivo no lugar.

E abaixo de uma obra exemplo de ing com paralelização :

find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}" 

Comentários

  • Foi uma primeira abordagem fácil para imaginar uma solução melhor. Se você deseja um comando funcional, faça:
  • find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'

Resposta

Se você acha que faz muito esse tipo de coisa, pesquise “rename.pl”. É um script perl, mas permite que você simplesmente o alimente com código perl (como /// expression), e ele fará uma renomeação em massa com base nessa expressão ou código.

Há uma versão básica aqui: http://stackoverflow.org/wiki/Rename.pl mas existem outras versões flutuando na rede. Ele existe há muito tempo.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *