Renomeie os arquivos incrementando um número no nome do arquivo


14

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

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 diferentes formatos (por exemplo, a pnge svgversão dos arquivos 03e 09acima), mas os números são consecutivos. Normalmente, existem 40 a 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. Portanto, se a nova imagem é a quinta do manuscrito, preciso renomear os arquivos no diretório para isso, a fim de abrir espaço para ela:

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 é a maneira mais direta a partir da linha de comando ou de um script ou macro para renumerar todos os arquivos começando em um determinado número? Eu tenho uma instalação padrão do Fedora Linux usando o bash.

Respostas:


11

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 - número da sua nova imagem.

PS. Coloque o script em outro diretório que não seja suas imagens. No diretório de imagens, deve haver apenas imagens nomeadas dessa maneira que você descreveu.


Parece promissor; tentarei em algumas horas quando voltar ao meu laptop.
robertc

Isso funcionará apenas se o nome do seu arquivo não tiver o prefixo de caracteres não numéricos
mems

@mems O OP afirma claramente que nomes de arquivos começam com um número
xhienne

2

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

  • o On qualificador glob para classificar as correspondências em ordem decrescente (en usar a ordem numérica, caso os nomes dos arquivos nem todos tenham zeros à esquerda na mesma largura);
  • o (l:WIDTH::FILLER:) sinalizador de expansão de parâmetro para preencher todos os números na mesma largura (a largura do número maior).
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, eis 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 se ajusta a 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

1

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


Não acho que seja o problema exato, que renumere todas as imagens todas as vezes. Eu só quero renumerar as imagens de um ponto específico.
11263 robertc

1

Mais fácil:

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

Você terá:

$ ls file*
file0.ext  file1.ext  file2.ext  file3.ext  file4.ext  file5.ext  file6.ext

Como adicionaria o zero inicial de 1 a 9? Lembre-se também de que pode haver dois arquivos 03.png e 03.svg.
Robertc #

1

Parece não haver muito interesse recente nessa questão, mas, se alguém a encontrar, há três questões aqui. Uma é como selecionar arquivos para renomear com base em critérios semânticos (o intervalo não é lexical e não pode ser especificado por curingas ou mesmo expressões regulares - a teoria dos autômatos diz que isso é mais complexo que um NFA). A segunda é como alterar um nome, modificando uma parte dele. O terceiro é como evitar a colisão de nomes. Um script no Bash e em muitos outros idiomas pode fazer essa transformação específica, mas a maioria de nós prefere não precisar escrever um programa toda vez que quisermos renomear um monte de arquivos. Com o meu rene.py (de código aberto e gratuito), você pode fazer o que quiser, mas são necessárias duas invocações para evitar o problema de colisão de nomes. Primeirorene ?.*/#7-80 %?.* Bincrementa todos os nomes no intervalo, adicionando um prefixo de% para evitar nomes existentes. Em seguida, rene %* *remove esse prefixo dos arquivos que o possuem. Eu descrevo isso em https://sourceforge.net/p/rene-file-renamer/discussion/examples/thread/f0fe8aa63c/

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.