Renomeia arquivos incrementando um número dentro do nome do arquivo

8

Eu tenho um diretório que contém arquivos de imagem numerados, algo assim:

01.png
02.png
03.png
03.svg
04.png
05.png
06.jpg
07.png
08.png
09.png
09.svg
10.png

Às vezes, pode haver várias versões de um arquivo em formatos diferentes (por exemplo, png e svg versão dos arquivos 03 e 09 acima), mas os números são consecutivos. Normalmente, existem 40-80 desses arquivos em cada diretório. Os números correspondem à ordem em que essas imagens aparecem em um manuscrito (um documento do Word, mas isso não é importante). Não há outra maneira de determinar a ordem das imagens.

Se eu adicionar uma nova imagem ao manuscrito, preciso colocar uma cópia da imagem nesse diretório com a numeração correta. Então, se a nova imagem é a quinta no manuscrito, eu preciso renomear os arquivos no diretório para isso, a fim de abrir espaço para isso:

01.png
02.png
03.png
03.svg
04.png
06.png
07.jpg
08.png
09.png
10.png
10.svg
11.png

Qual é o caminho mais direto da linha de comando, ou de um script ou macro para renumerar todos os arquivos que começam em um determinado número? Eu tenho uma instalação padrão do Fedora Linux usando o bash.

    
por robertc 11.06.2012 / 16:04

4 respostas

7

Eu acho que deveria fazer o trabalho:

#!/bin/bash

NEWFILE=$1

for file in 'ls|sort -g -r'
do
    filename=$(basename "$file")
    extension=${filename##*.}
    filename=${filename%.*}

    if [ $filename -ge $NEWFILE ]
    then
        mv "$file" "$(($filename + 1))".$extension
    fi
done

O script usa um parâmetro - o número da sua nova imagem.

PS. Coloque script em outro diretório que suas imagens. No diretório de imagens, deve haver apenas imagens nomeadas dessa maneira.

    
por 11.06.2012 / 16:59
2

Isso seria mais fácil em zsh, onde você pode usar

  • o qualificador de glob On para classificar as correspondências em ordem decrescente (e n para usar a ordem numérica, caso os nomes dos arquivos não tenham zeros à esquerda na mesma largura);
  • o sinalizador de expansão do parâmetro (l:WIDTH::FILLER:) para preencher todos os números até o mesma largura (a largura do maior número).
break=$1   # the position at which you want to insert a file
setopt extended_glob
width=
for x in [0-9]*(nOn); do
  n=${x%%[^0-9]*}
  if ((n < break)); then break; fi
  ((++n))
  [[ -n $width ]] || width=${#n}
  mv $x ${(l:$width::0:)n}${x##${x%%[^0-9]*}}
done

No bash, aqui está um script que assume que os arquivos são preenchidos com uma largura fixa (caso contrário, o script não renomeia os arquivos corretos) e os blocos para uma largura fixa (que deve ser especificada).

break=$1      # the position at which you want to insert a file
width=9999    # the number of digits to pad numbers to
files=([0-9]*)
for ((i=#((${#files}-1)); i>=0; --i)); do
  n=${x%%[^0-9]*}
  x=${files[$i]}
  if ((n < break)); then continue; fi
  n=$((n + 1 + width + 1)); n=${n#1}
  mv -- "${files[$i]}" "$n${x##${x%%[^0-9]*}}"
done
    
por 12.06.2012 / 03:39
1

Esse problema exato é abordado em este artigo . Observe que você teria que modificá-lo para suportar os formatos SVG e PNG, adicionando uma segunda etapa de MV.

    
por 11.06.2012 / 16:39
0

Mais fácil:

touch file'ls file* | wc -l'.ext

Você receberá:

$ ls file*
file0.ext  file1.ext  file2.ext  file3.ext  file4.ext  file5.ext  file6.ext
    
por 05.04.2018 / 13:35