Cambiar el nombre de archivos agregando el sufijo "ciclismo"

Cambiar el nombre de archivos agregando el sufijo "ciclismo"

Tengo un directorio que contiene subdirectorios que contienen muchos archivos llamados como:

file1.tif
file2.tif
file3.tif
file4.tif
file5.tif
file6.tif
file7.tif...

Quiero agregar un sufijo "cíclico" c1y para obtener los nombres de los archivos c2:c3

file1c1.tif
file2c2.tif
file3c3.tif
file4c1.tif
file5c2.tif
file6c3.tif
file7c1.tif...

Y esto en todos los subdirectorios del directorio superior.

Pero no puedo encontrar cómo hacerlo.

¿Es eso posible? ¿Cómo?

Respuesta1

Con find+ el basado en Perl prename(también conocido como renameen algunos Ubuntus anteriores), puede hacer coincidir la secuencia de dígitos antes de un literal .y luego escribirlo en el formato deseado usando la división de módulo, por ejemplo.

find . -name '*.tif' -execdir prename -vn -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

(Las -vnbanderas le permiten hacer un 'ensayo' para ver cómo se cambiaría el nombre de los archivos antes de confirmarlos).


Ex. dado

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   ├── file4.tif
│   ├── file5.tif
│   ├── file6.tif
│   └── file7.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

4 directories, 14 files

Entonces

find . -name '*.tif' -execdir prename -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

resultados en

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   ├── file4c1.tif
│   ├── file5c2.tif
│   ├── file6c3.tif
│   └── file7c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

4 directories, 14 files

Respuesta2

Editar según el comentario:

Si desea realizar un ciclo del contador, es decir, <number>para c<number>realizar un ciclo entre 1 y 3:

Ejecución en seco:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do 
        echo mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Acción:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do 
        mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Ejemplo:

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   └── file4.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

$ shopt -s globstar
$ for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do \
    echo mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
/home/foobar/bar
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
mv -i file4.tif file4c1.tif
/home/foobar/foo
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
/home/foobar/foo/egg
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
/home/foobar/spam
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif

$ for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do \
    mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   └── file4c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

Respuesta original:

Con bash:

shopt -s globstar
for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob \
    && for f in file*.tif; do echo mv -i "$f" "${f%.tif}"c${count}.tif; \
        ((count++)); done ); done
  • Aquí estamos recorriendo los nombres de los directorios, globstarla opción de shell nos permite recorrer el directorio de forma recursiva.

  • La parte interna ()se ejecuta en un subshell, esto es para evitar que cdse modifique en el shell actual.

  • Estamos cdingresando a los directorios, buscando los file*.tifarchivos y cambiándoles el nombre según sea necesario.

  • manteniendo un contador incremental, countpara cada archivo mientras se cambia el nombre


Lo anterior es una ejecución en seco y le mostrará el directorio donde se realizará el cambio de nombre y qué mvcomando se ejecutará. Si está satisfecho, haga:

shopt -s globstar
for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && \
  for f in file*.tif; do mv -i "$f" "${f%.tif}"c${count}.tif; ((count++)); done ); done

Hay una advertencia: como Shell realiza una clasificación léxica, los archivos, por ejemplo, file10.tifse cambiarán de nombre antes de file2.tif. Si no desea eso, ordene un poco antes de cambiar el nombre o use la opción zshwith numericglobsort.

Respuesta3

Gracias a heemayl, todo se solucionó. Tuvimos que modificar un poco el bucle de incremento de ciclo indicado, ya que no funcionaba en nuestras manos. Cambiamos: if ((count=3)) a: if (("$count"==3)) El código final que ahora estamos usando exitosamente es:

    shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in *.tif; do 
       echo mv -i "$f" "${f%.tif}"c${count}.tif

if (("$count"==3)); then 
count=1
        else 
((count++))
        fi
     done ) 
done

Gracias de nuevo a heemayl por su ayuda y paciencia...

información relacionada