Como renomear para tamanho fixo

5

Eu tenho arquivos nomeados como 0-n.jpg para n de 1 a 500, por exemplo.

O problema é que um cara usando o Windows não usou zeros à esquerda, então quando eu faço ls eu obtenho

0-100.jpg
0-101.jpg
...
0-10.jpg
...
0-199.jpg
0-19.jpg
0-1.jpg

Portanto, gostaria de renomeá-los para inserir os zeros à esquerda, para que o resultado de ls possa ser

0-001.jpg
0-002.jpg
...
0-100.jpg
...
0-499.jpg
0-500.jpg

Em outras palavras, eu gostaria de todos os arquivos com os mesmos comprimentos de nome de arquivo.

Eu tentei esta solução , mas estou recebendo uma sequência de erros como

bash: printf: 0-99: invalid number
    
por Sigur 16.09.2014 / 00:04

4 respostas

10

Se o seu sistema tiver o comando rename baseado em perl, você poderá fazer algo como

rename -- 's/(\d+)-(\d+)/sprintf("%d-%03d",$1,$2)/e' *.jpg

Teste-o usando as opções -v (verbose) e -n (no-op):

$ rename -vn -- 's/(\d+)-(\d+)/sprintf("%d-%03d",$1,$2)/e' *.jpg
0-10.jpg renamed as 0-010.jpg
0-19.jpg renamed as 0-019.jpg
0-1.jpg renamed as 0-001.jpg
    
por 16.09.2014 / 00:19
3

Se você tiver zsh shell, poderá fazer algo como abaixo.

zmv '([0-9])-([0-9]##).(jpg)' '$1-${(l:3::0:)2}.$3'

Teste

touch 0-1.jpg
touch 0-23.jpg
touch 0-345.jpg
touch 0-6.jpg
touch 0-05.jpg

Altere o shell para zsh e, se zmv não estiver carregado, você poderá fazer autoload zmv .

Agora, você pode adicionar -n flag ao comando zmv para ver o que acontecerá se você executar o comando zmv . Estou executando o comando como

zmv -n '([0-9])-([0-9]##).(jpg)' '$1-${(l:3::0:)2}.$3'

A saída é

zmv -n '([0-9])-([0-9]##).(jpg)' '$1-${(l:3::0:)2}.$3'
mv -- 0-05.jpg 0-005.jpg
mv -- 0-1.jpg 0-001.jpg
mv -- 0-23.jpg 0-023.jpg
mv -- 0-6.jpg 0-006.jpg

Se você estiver satisfeito com o renomeado dos nomes dos arquivos, poderá remover o sinalizador -n .

Referências

Obrigado ao usuário Gnouc por esclarecer minha dúvida sobre essa questão que eu havia postado como outra pergunta para obter essa solução e o link para a resposta do Gnouc é isso .

    
por 16.09.2014 / 16:17
2

outra solução caso você não tenha "renomear:

for file in *.jpg; do
   [ -f "$file" ] || continue  #skips if no jpg file present in current dir
   echo "${file}" | awk -F'[-.]' '
      {   new=sprintf("%03d",$2); 
          print "echo TESTING mv ", $0," ",$1"-"new"."$3 
      }'
done | bash

(edit: moveu o | bash então ele é invocado apenas uma vez, e não uma vez por arquivo. E esse loop rápido não é "weird filename" amigável, mas pode ser limpo (para manipular arquivos com espaços, etc))

e remova as duas palavras echo TESTING para realmente fazer o mv ... , assim que tiver certeza de que está fazendo o que deseja fazer.

    
por 16.09.2014 / 10:34
1

Aqui está outra abordagem. Como você só precisa renomear um subconjunto específico de arquivos e, como você já sabe quais são, basta listá-los e renomeá-los:

for i in {1..99}; do mv -- 0-$i.jpg 0-$(printf '%03d\n' $i).jpg; done

Isso listará os números de 1 a 99, salvando cada valor como $i . Você não se importa com o resto, já que eles já estão nomeados corretamente. Em seguida, você renomeia 0-$i.jpg para a versão preenchida. A diretiva printf %03d imprimirá um número adicionando 0s ao lado esquerdo se ele tiver menos de 3 caracteres de comprimento. O resultado é que todos os seus arquivos problemáticos serão renomeados.

    
por 16.09.2014 / 16:12