renomeando a ordem de incremento de múltiplos arquivos

1

Eu tenho os seguintes arquivos

SSt12.precip.374.sub.climatology.ctl
SSt12.precip.2874.sub.climatology.ctl
SSt12.precip.3764.sub.climatology.ctl
SSt12.precip.6774.sub.climatology.ctl

Eu quero renomear os arquivos como

SSt12.precip.1.sub.climatology.ctl
SSt12.precip.2.sub.climatology.ctl
SSt12.precip.3.sub.climatology.ctl
SSt12.precip.4.sub.climatology.ctl
    
por sourabh bal 20.05.2014 / 19:28

4 respostas

3

com zsh :

$ autoload zmv
$ n=0; zmv -n '(*.)<->(*.ctl)(#qn)' '$1$[++n]$2'
mv -- SSt12.precip.374.sub.climatology.ctl SSt12.precip.1.sub.climatology.ctl
mv -- SSt12.precip.2874.sub.climatology.ctl SSt12.precip.2.sub.climatology.ctl
mv -- SSt12.precip.3764.sub.climatology.ctl SSt12.precip.3.sub.climatology.ctl
mv -- SSt12.precip.6774.sub.climatology.ctl SSt12.precip.4.sub.climatology.ctl

(faça novamente sem o -n para realmente executar a renomeação).

Com as ferramentas GNU e supondo que nomes de arquivos não contenham caracteres de nova linha, você poderia fazer:

ls -v | awk -F. -vOFS=. -vORS='
$ autoload zmv
$ n=0; zmv -n '(*.)<->(*.ctl)(#qn)' '$1$[++n]$2'
mv -- SSt12.precip.374.sub.climatology.ctl SSt12.precip.1.sub.climatology.ctl
mv -- SSt12.precip.2874.sub.climatology.ctl SSt12.precip.2.sub.climatology.ctl
mv -- SSt12.precip.3764.sub.climatology.ctl SSt12.precip.3.sub.climatology.ctl
mv -- SSt12.precip.6774.sub.climatology.ctl SSt12.precip.4.sub.climatology.ctl
' '/\.ctl$/{print;$3=++n;print}' | xargs -r0n2 echo mv --

(remova o echo para realmente renomear)

    
por 20.05.2014 / 22:02
1
printf 'cp SSt12.precip.374.sub.climatology.ctl \
   SSt12.precip.%d.sub.climatology.ctl\n' $(seq 5) | 
. /dev/stdin

Aparentemente você quis dizer renomear - desculpe pelo mal-entendido.

Mas se isso acontecer ... diga 374 - 378 ...

printf 'n=%d ; mv SSt12.precip.$((373+n)).sub.climatology.ctl \
   SSt12.precip.${n}.sub.climatology.ctl\n' $(seq 5) | 
. /dev/stdin

Com relação ao seu comentário acima, supondo que eles estejam no mesmo diretório e sejam os únicos arquivos que corresponderão a SSt12.precip.*.sub.climatology.ctl :

set -- SSt12.precip.*[67]4.sub.climatology.ctl
printf 'echo mv %s SSt12.precip.$((n=n+1)).sub.climatology.ctl\n' "$@" | 
    . /dev/stdin

Eu nerferei com echo acima, para que você não acabe com nenhum arrependimento na minha conta. Em sua forma atual, apenas mostrará o que deseja fazer. Remova echo e os arquivos são seus para se mover ou perder.

Veja o comentário de Stephane abaixo para uma nota sobre a ordem de classificação adequada - ele está certo.

    
por 20.05.2014 / 19:41
1

Supondo que você tenha vários arquivos e não o mesmo, e deseje renomear cada um deles, faça o seguinte:

for i in *ctl; do echo "$i"; done | 
    sort -t'.' -nk3 | 
        awk -F'.' -v OFS='.' '{printf "mv %s ", $0; $3=NR;print}' |
            sh

O texto acima assume que os nomes dos seus arquivos são exatamente como você mostra na sua pergunta. Todos eles têm um número como o campo separado por 3 pontos e todos terminam com ctl .

    
por 20.05.2014 / 19:51
1

O primeiro obstáculo é colocar os arquivos na ordem correta. O padrão curinga SSt12.precip.*.sub.climatology.ctl expande os nomes dos arquivos em ordem lexicográfica, não em ordem numérica, portanto, coloca os arquivos na ordem 2874, 374, 3764, 6774.

No zsh, isso é facilmente solucionado graças ao n qualificador da glob (%código%). Em outros shells, isso requer mais trabalho. Você pode extrair os números e classificá-los. Aqui está uma maneira que funciona desde que seus nomes de arquivo não contenham nenhuma nova linha. Eu extraio o número retirando os dois primeiros segmentos separados por pontos e depois todos, exceto o primeiro segmento separado por pontos.

number=1
for x in SSt12.precip.*.sub.climatology.ctl; do
  number="${x#*.*.}"; number="${number%%.*}"
  printf "%d %s\n" "$number" "$x"
done | sort -k1,1n |
while IFS= read -r filename; do
  filename=${filename#* }
  suffix=${filename#*.*.*.}
  prefix=${filename%.*."$suffix"}
  mv -- "$filename" "$prefix.$number.$suffix"
  number=$((number+1))
done
    
por 21.05.2014 / 09:48