Batch renomeia arquivos para uma numeração seqüencial

1

Estou tentando renomear em lote vários arquivos no meu shell e, embora haja muito material sobre isso na Internet, não consigo encontrar uma solução para o meu caso específico.

Eu tenho um monte de arquivos que têm (o que parece ser) um "timestamp-id":

abc_128390.png
abc_138493.png
abc_159084.png
...

que gostaria de trocar por um contador:

abc_001.png
abc_002.png
abc_003.png
...

Minha abordagem (abundante) ingênua seria algo como:

mv abc_*.png abc_{001..123}.png

Além disso, não consegui descobrir uma maneira de fazê-lo funcionar com for -loop.

FWIW, infelizmente rename não está disponível neste sistema em particular.

Qualquer conselho seria muito apreciado!

    
por NicApicella 31.01.2018 / 13:12

5 respostas

3

Não consigo pensar em uma solução que lide com o incremento do contador de maneira mais inteligente, mas isso deve funcionar:

i=0
for fi in abc_??????.png; do
    mv "$fi" abc_$i.png
    i=$((i+1))
done

Deve ser seguro usar abc_*.png porque ele é expandido antes que o primeiro mv seja executado, mas pode ser útil ser muito específico, pois você deseja apenas arquivos com um registro de data e hora de seis caracteres no final .

    
por 31.01.2018 / 13:16
1

com zsh :

set -o extendedglob # best in ~/.zshrc
typeset -A count
(zmv -n '([^0-9]##)<->(*)(#qn)' '$1${(l:3::0:)$((++count[$1/$2]))}$2')

Remova o -n quando estiver feliz.

Exemplo:

$ ls
a1b.png  abc_128390.png  abc_159084.png  x12y.png
a2b.png  abc_138493.png  a.png           x2y.png
$ typeset -A count
$ (zmv -n '([^0-9]##)<->(?*)(#qn)' '$1${(l:3::0:)$((++count[$1/$2]))}$2')
mv -- a1b.png a001b.png
mv -- a2b.png a002b.png
mv -- abc_128390.png abc_001.png
mv -- abc_138493.png abc_002.png
mv -- abc_159084.png abc_003.png
mv -- x2y.png x001y.png
mv -- x12y.png x002y.png
    
por 31.01.2018 / 14:48
1

Com o utilitário rename como parte dos pacotes Perl, você faria:

rename -n 'our $i; s/_.*/sprintf("_%03d.png", $i++)/e' *.png

Nota: -n é para execução a seco, remova-o para renomear a aplicação em arquivos.

    
por 31.01.2018 / 19:20
0

Evite substituir os arquivos existentes:

i=1
for fi in abc_??????.png; do
    a="abc_$(printf '%04d' "$i").png"
    if [[ -e $a ]]; then
        echo "file $a exist, not moving $fi"
    else
        mv "$fi" "$a"
    fi
    i=$((i+1))
done
    
por 31.01.2018 / 18:22
0

você pode usar o corte para recortar partes do nome do arquivo, por exemplo, se quiser renomear arquivos como

"1 first.jpg"
"2 second.jpg"
...

para

"10 first.jpg"
"20 second.jpg"
...

você pode usar

for i in *jpg; do
  mv -iv "$i" "$(echo "$i"|cut -d\  -f1)0 $(echo "$i"|cut -d\  -f2-99)";
done
    
por 14.08.2018 / 20:43