Renomeie vários arquivos usando o script Bash


27

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

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

Quero renomear para o seguinte formato:

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

Eu estava lendo sobre o comando renomear e tente fazer dessa maneira, mas não faz 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 errado?



2
Você não pode ter uma expressão de 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á?
Kojiro # 26/14

@ Kiwy Essa pergunta é sobre como remover uma parte do nome do arquivo. Portanto, duplamente duvidoso.
a CVn 26/03

2
Da próxima vez, descreva as alterações no nome do arquivo que você deseja fazer (eu tive que analisar isso por um bom tempo antes de ver as diferenças e semelhanças). Exemplos são bons, mas uma descrição e exemplos são ainda melhores.
a CVn 26/03

Respostas:


42

Você estava certo ao considerar renomear primeiro. A sintaxe é um pouco estranha se você não está acostumado a expressões regulares, mas é de longe a rota mais rápida / mais curta depois de saber o que está fazendo:

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

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

E um equipamento de teste ( -vnsignifica ser detalhado, mas não faça nada) 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

8
Note que este é o nome do Perl no Debian e derivados (Ubuntu, Mint,…). Em outras distribuições Linux, renameexiste uma ferramenta de renomeação de arquivos completamente diferente (que o Debian envia como rename.ul).
Gilles 'SO- stop be evil'

Se a sua falta distributiva dessa ferramenta, consulte a resposta do @Michael Campbell. Eu acho que todo distributivo substitui o padrão renamecomo o debian.
Astery

25

Isso deve fazer o truque:

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

Ele substitui a sequência entre o 4º e o 12º caractere por "25032014".


isso for f in file*; do mv $f ${f/${f:4:4}/2503}; donetambém funciona.
precisa

Isso é bom. Se você quer apenas uma palavra regular para substituir a palavra, ela funciona como sed. por exemplo,for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
Eric

11
@ Eric - publiquei sua resposta como alternativa, porque acho que é mais clara e elegante. Se você também quiser publicá-lo como resposta - eu excluirei o meu. Obrigado!
Yehosef


Isso me dá um erro: "mv: target 'FILE_NAME' não é um diretório"
Aubrey

10

Esta é realmente a resposta de Eric de cima - mas é uma resposta elegante, por isso estou publicando-a como uma resposta adequada para chamar mais atenção.

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

1
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 fazer o truque. Nota - eu não tenho o hábito de entregar comandos mass mv - como está escrito, é apenas um eco. Você terá que resolver isso antes que funcione.


1

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

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

Ele renomeará todos os arquivos no local.

E abaixo um exemplo de trabalho com paralelização :

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

Foi uma primeira abordagem fácil imaginar uma solução melhor. Se você deseja um comando de trabalho, faça o seguinte:
dtrckd

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

0

Se você acha que faz muito esse tipo de coisa, procure "rename.pl". É um script perl, mas permite simplesmente alimentá-lo com código perl (como expressão ///) e 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 há outras versões flutuando pela rede. Tem sido em torno de idades e idades e idades.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.