Cambie el nombre de los archivos incrementando un número dentro del nombre del archivo

14

Tengo un directorio que contiene archivos de imagen numerados, algo como esto:

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

A veces puede haber varias versiones de un archivo en diferentes formatos (por ejemplo. Una pngy svgversión del 03y 09archivos anteriores) pero los números son de otra manera consecutiva. Por lo general, hay 40-80 de estos archivos en cada directorio. Los números corresponden al orden en que aparecen estas imágenes en un manuscrito (un documento de Word, pero eso no es importante). No hay otra forma de determinar el orden de las imágenes.

Si agrego una nueva imagen al manuscrito, necesito colocar una copia de la imagen en este directorio con la numeración correcta. Entonces, si la nueva imagen es la quinta en el manuscrito, necesito cambiar el nombre de los archivos en el directorio a este para dejar espacio:

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

¿Cuál es la forma más directa desde la línea de comando, o desde un script o macro para renumerar todos los archivos que comienzan en un número determinado? Tengo una instalación estándar de Fedora Linux usando bash.

robertc
fuente

Respuestas:

11

Creo que debería hacer el trabajo:

#!/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

La secuencia de comandos toma un parámetro: número de imágenes nuevas.

PD. Coloque el script en otro directorio que no sean sus imágenes. En el directorio de imágenes solo debe haber imágenes nombradas de esta manera que usted describió.

pbm
fuente
Esto parece prometedor, lo intentaré en unas horas cuando vuelva a mi computadora portátil.
robertc
Esto solo funcionará si su nombre de archivo no está prefijado por caracteres no numéricos
mems
@mems El OP establece claramente que los nombres de archivo comienzan con un número
xhienne
2

Esto sería más fácil en zsh, donde puedes usar

  • el On calificador global para ordenar las coincidencias en orden decreciente (y npara usar el orden numérico, en caso de que los nombres de los archivos no tengan ceros al mismo ancho);
  • la (l:WIDTH::FILLER:) bandera de expansión de parámetros para rellenar todos los números con el mismo ancho (el ancho del número más grande).
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

En bash, aquí hay un script que asume que los archivos están rellenados a un ancho fijo (de lo contrario, el script no cambiará el nombre de los archivos correctos) y los pads a un ancho fijo (que debe especificarse).

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
Gilles 'SO- deja de ser malvado'
fuente
1

Este problema exacto está cubierto en este artículo . Tenga en cuenta que tendría que modificarlo para admitir los formatos SVG y PNG, agregando un segundo paso de MV.

Jodie C
fuente
No creo que sea el problema exacto, va a renumerar todas las imágenes cada vez. Solo quiero renumerar las imágenes desde un punto en particular.
robertc
1

Más fácil:

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

Usted obtendrá:

$ ls file*
file0.ext  file1.ext  file2.ext  file3.ext  file4.ext  file5.ext  file6.ext
Hugoren Martinako
fuente
¿Cómo agregaría el cero inicial para 1-9? También recuerde que puede haber dos archivos 03.png y 03.svg.
robertc
1

No parece haber mucho interés reciente en esta pregunta, pero, si alguien se topa con ella, hay tres problemas aquí. Una es cómo seleccionar archivos para renombrarlos según criterios semánticos (el rango no es léxico y no puede especificarse mediante comodines o incluso expresiones regulares; la teoría de autómatas dice que esto es más complejo que un NFA). El segundo es cómo cambiar un nombre modificando una parte de él. El tercero es cómo evitar la colisión de nombres. Un script en Bash y muchos otros idiomas puede hacer esta transformación específica, pero la mayoría de nosotros preferiría no tener que escribir un programa cada vez que queramos renombrar un grupo de archivos. Con mi rene.py (gratuito y de código abierto) puede hacer lo que quiera, pero se necesitan dos invocaciones para evitar el problema de colisión de nombres. primerorene ?.*/#7-80 %?.* Bincrementa todos los nombres en el rango, agregando un prefijo de% para evitar nombres existentes. Luego rene %* *elimina este prefijo de los archivos que lo tienen. Describo esto en https://sourceforge.net/p/rene-file-renamer/discussion/examples/thread/f0fe8aa63c/

David McCracken
fuente