Você quase teve. Você só precisa tornar as strings literais e a concatenação de strings explícitas dentro da substituição /e
-modified, usando aspas e o operador dot.
rename 's/0([2-4])([\s\S]+)/"0".($1+1).$2/e' *
Vamos supor que eu tenha cinco arquivos mp3:
01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
05-trackxyz.mp3
Agora eu dou uma rápida olhada nos arquivos (apenas o mplayer no console fará o truque) e descubro que as faixas estão em ordem errada . 05 é na verdade 02 e o restante terá que ser renomeado. Então, primeiro eu farei uma renomeação temporária:
01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
00-trackxyz.mp3
Agora precisamos de um "turno": 02 deve se tornar 03, 03 deve se tornar 04 e 04 deve se tornar 05. Para minimizar a confusão, o ex-05 (agora 00) será apenas% depois.
Minha abordagem foi esta: (perl mv
, por Larry Wall, padrão aqui no Debian)
rename 's/0([2-4])([\s\S]+)/0($1+1)$2/' *
bem como (mais tarde, depois de mais alguns RTFMs)
rename 's/0([2-4])([\s\S]+)/0($1+1)$2/e' *
Nenhum deles funcionou, especialmente porque o modificador rename
não aceita mais nada mas avaliações e lançará um erro quando você tentar combinar as avaliações com strings. O /e[val]
pode fazer isso muito bem, e. g. bash
será avaliado como foo$((1+6))
.
Então, como eu posso fazer isso (o one-liner é preferido, não pretendo escrever um script autônomo só para isso)?
one-liner preferred, not intending to write a whole standalone script just for this
Quando as coisas ficam tão complicadas, não vejo motivo para não escrever um script. Você nunca vai se lembrar de como fazer isso de uma corrida para outra, então você acabará reinventando-a a cada vez ou encerrando-a em um script de qualquer maneira.
Para uma coisa pequena como essa, geralmente começo a tentar resolvê-lo no Bash:
#!/bin/bash
if [ -z "$1" ] ; then echo Need arguments. ; exit 1 ; fi
typeset -i i=1
for f in "$*"
do
tailbits='echo "$f" | sed -e 's/^[0-9]+//''
mv "$f" sertmp-'printf %02d $i'"$tailbits"
i=i+1
done
for f in "sertmp-*"
do
mv "$f" 'echo "$f" | sed -e s/^sertmp-//'
done
Basicamente, este script retira quaisquer dígitos iniciais e, em seguida, coloca um número de série crescente preenchido com zero na frente, com os arquivos numerados de acordo com a ordem em que você os passa para o script.
Ele faz isso em dois estágios, com sertmp-
prefixos para a primeira passagem para evitar qualquer risco de colisão de nomes. Se você chamar este script mp3-renamer
e chamá-lo como:
$ mp3-renamer 01-foo.mp3 03-bar.mp3 04-qux.mp3
você se depara com uma colisão trivial na primeira renomeação, se você não usar 2 passes para fazer a renomeação. ( 01-foo.mp3
- > 01-foo.mp3
.)
Se você ligar assim, no entanto:
$ mp3-renamer 02-foo.mp3 01-foo.mp3
você apaga acidentalmente 01-foo.mp3
na primeira renomeação com uma renomeação de 1 passagem.
Se o problema ficar mais complicado, eu o reescreverei em Perl. Nesse ponto, você pode usar um hash para manter o antigo e novo mapeamento de nome e usar um código inteligente para elaborar a ordem correta para fazer as renomeações, a fim de evitar a necessidade de 2 passagens.
Tags rename debian perl arithmetic