bash - varios - Renombrar archivos en una carpeta a números secuenciales
renombrar carpetas masivamente (22)
Aquí hay otra solución con el comando "cambiar el nombre":
find -name ''access.log.*.gz'' | sort -Vr | rename ''s/(/d+)/$1+1/ge''
Quiero cambiar el nombre de los archivos en un directorio a números secuenciales. En función de la fecha de creación de los archivos.
Por ejemplo sadf.jpg
a 0001.jpg
, wrjr3.jpg
a 0002.jpg
y así sucesivamente, el número de ceros a la izquierda según la cantidad total de archivos (sin necesidad de ceros adicionales si no es necesario).
Belleza en una línea
ls | cat -n | while read n f; do mv "$f" "$n.extension"; done
cambie la extensión con PNG deseado, Jpg o algún otro.
De nuevo, se usa la solución de Pero con poca modificación, ya que find
recorrerá el árbol de directorios en el orden en que los elementos se almacenan dentro de las entradas del directorio. Esto (en su mayoría) será consistente desde la ejecución hasta la ejecución, en la misma máquina y esencialmente será "orden de creación de archivo / directorio" si no ha habido eliminaciones.
Sin embargo, en algún caso debe obtener un orden lógico, por ejemplo, por nombre, que se utiliza en este ejemplo.
find -name ''*.jpg'' | sort -n | # find jpegs
gawk ''BEGIN{ a=1 }{ printf "mv %s %04d.jpg/n", $0, a++ }'' | # build mv command
bash # run that command
Este oneliner enumera todos los archivos en el directorio actual, ordena por fecha y hora de creación en orden inverso (significa que el archivo más antiguo está al principio) y cambia el nombre automáticamente con ceros finales según lo requiera la cantidad de archivos. La extensión de archivo se conservará.
Por lo general, solo tengo una carpeta desde hace años para fotos y películas de teléfonos móviles. Al aplicar este comando, mis imágenes y películas están listas para una presentación de diapositivas en el orden correcto en la televisión o archivo también.
Tenga en cuenta que si tiene colisiones de nombre de archivo, está perdiendo archivos. Así que primero cambie el nombre a algo extraño como temp001.jpg
y luego ejecute con su nombre de archivo final.
DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done
Este script ordenará los archivos por fecha de creación en Mac OS bash. Lo uso para cambiar el nombre masivo de videos. Simplemente cambie la extensión y la primera parte del nombre.
ls -trU *.mp4| awk ''BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4/n", $0, a++ }'' | bash
Intente usar un loop, let
, y printf
para el relleno:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
usar el indicador -i
evita sobrescribir automáticamente los archivos existentes.
La mayoría de las otras soluciones sobrescribirán los archivos existentes ya nombrados como un número. Esto es particularmente un problema si ejecuta el script, agrega más archivos y luego ejecuta el script nuevamente.
Este script cambia el nombre de los archivos numéricos existentes primero:
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can''t opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(/..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(/.[^.]+)$/ ? $1 : '''';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ //A/./.?/z/;
my $ext = $file =~ /(/.[^.]+)$/ ? $1 : '''';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
La respuesta de Pero me consiguió aquí :)
Quería cambiar el nombre de los archivos en relación con el tiempo, ya que los visores de imágenes no mostraban las imágenes en orden cronológico.
ls -tr *.jpg | # list jpegs relative to time
gawk ''BEGIN{ a=1 }{ printf "mv %s %04d.jpg/n", $0, a++ }'' | # build mv command
bash # run that command
Me gusta la solución de gauteh por su simplicidad, pero tiene un inconveniente importante. Cuando se ejecuta en miles de archivos, puede obtener el mensaje "lista de argumentos demasiado larga" ( más sobre esto ), y segundo, la secuencia de comandos puede ser realmente lenta. En mi caso, al ejecutarlo en aproximadamente 36,000 archivos, el script se movió aprox. un artículo por segundo! No estoy seguro de por qué sucede esto, pero la regla que obtuve de los colegas fue " find
es tu amigo" .
find -name ''*.jpg'' | # find jpegs
gawk ''BEGIN{ a=1 }{ printf "mv %s %04d.jpg/n", $0, a++ }'' | # build mv command
bash # run that command
Para contar elementos y construir comandos, se usó gawk . Tenga en cuenta la principal diferencia, sin embargo. De forma predeterminada, find
búsquedas de archivos en el directorio actual y sus subdirectorios, de modo que asegúrese de limitar la búsqueda en el directorio actual solamente, si es necesario (use man find
para ver cómo).
Ordenado por tiempo, limitado a jpg, ceros a la izquierda y un nombre base (en caso de que quieras uno):
ls -t *.jpg | cat -n | /
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(todo en una línea, sin el /
)
Para renumerar 6000, archivos en una carpeta, puede usar la opción ''Cambiar nombre'' del programa ACDsee.
Para definir un prefijo use este formato: ####"*"
A continuación, establezca el número de inicio y presione Cambiar nombre y el programa cambiará el nombre de todos los 6000 archivos con números secuenciales.
Para trabajar en todas las situaciones, ponga / "para los archivos que tengan espacio en el nombre
find . -name ''*.jpg'' | gawk ''BEGIN{ a=1 }{ printf "mv /"%s/" %04d.jpg/n", $0, a++ }'' | bash
Si su rename
no admite -N
, puede hacer algo como esto:
ls -1 -c | xargs rename -n ''s/.*/our $i; sprintf("%04d.jpg", $i++)/e''
Editar Para comenzar con un número dado, puede usar el código (algo feo) a continuación, solo reemplace 123 con el número que desee:
ls -1 -c | xargs rename -n ''s/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e''
Esto enumera los archivos en orden por fecha de creación (el más nuevo primero, agrega -r
a ls para ordenar de forma inversa), luego envía esta lista de archivos para cambiar el nombre. Rename utiliza el código perl en la expresión regular para formatear e incrementar el contador.
Sin embargo, si se trata de imágenes JPEG con información EXIF, recomendaría exiftool
Esto es de la documentación exiftool , bajo "Renombrar ejemplos"
exiftool ''-FileName<CreateDate'' -d %Y%m%d_%H%M%S%%-c.%%e dir
Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading ''-'' if the file already exists ("%-c"), and
preserving the original file extension (%e). Note the extra ''%'' necessary to escape the filename codes (%c and %e) in the date format string.
Supongamos que tenemos estos archivos en un directorio, enumerados en orden de creación, el primero es el más antiguo:
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
entonces ls -1cr
saca exactamente la lista de arriba. A continuación, puede usar el rename
:
ls -1cr | xargs rename -n ''s/^[^/.]*(/..*)?$/our $i; sprintf("%03d$1", $i++)/e''
que salidas
rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
La advertencia "uso de valor no inicializado [...]" se muestra para archivos sin extensión; puedes ignorarlo
Elimina -n
del comando de rename
para aplicar el cambio de nombre.
Esta respuesta está inspirada en la respuesta de Lucas de abril de 2014 . Ignora el requisito de Gnutt de establecer el número de ceros a la izquierda según la cantidad total de archivos.
También puedes usar ls
ls *.JPG| awk ''BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg/n", $0, a++ }'' | bash
Tuve un problema similar y escribí un guión de shell por ese motivo. He decidido publicarlo independientemente de que ya se hayan publicado muchas buenas respuestas porque creo que puede ser útil para alguien. ¡Siéntete libre de mejorarlo!
@Gnutt El comportamiento que desea se puede lograr escribiendo lo siguiente:
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
Si se -r
la opción -r
, el escariado solo se simulará (debería ser útil para la prueba).
La otión L describe la longitud del número objetivo (que se rellenará con ceros a la izquierda) también es posible agregar un prefijo / sufijo con las opciones -p <prefix>
-s <suffix>
.
En caso de que alguien quiera ordenar los archivos numéricamente antes de que se -o modtime
, simplemente elimine la opción -o modtime
.
Un bash one liner muy simple que conserva las extensiones originales, agrega los ceros iniciales y también funciona en OSX:
num=0; for i in *; do mv "$i" "$(printf ''%04d'' $num).${i#*.}"; ((num++)); done
Versión simplificada de http://ubuntuforums.org/showthread.php?t=1355021
con el comando "renombrar"
rename -N 0001 -X ''s/.*/$N/'' *.jpg
o
rename -N 0001 ''s/.*/$N.jpg/'' *.jpg
usar la solución de Pero en OSX requirió algunas modificaciones. Solía:
find . -name ''*.jpg'' /
| awk ''BEGIN{ a=0 }{ printf "mv /"%s/" %04d.jpg/n", $0, a++ }'' /
| bash
nota: las barras invertidas están ahí para la continuación de la línea
editar 20 de julio de 2015: se incorporó la opinión de @ klaustopher para citar el argumento /"%s/"
del comando mv
para admitir nombres de archivos con espacios.
En OSX , instale el script de cambio de nombre de Homebrew:
brew install rename
Entonces puedes hacerlo realmente ridículamente fácil:
rename -e ''s/.*/$N.jpg/'' *.jpg
O para agregar un buen prefijo:
rename -e ''s/.*/photo-$N.jpg/'' *.jpg
a=1
for i in *.jpg; do
mv -- "$i" "$a.jpg"
a=`expr $a + 1`
done
ls -1tr | rename -vn ''s/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e''
renombrar -vn - eliminar n para el modo de prueba desactivada
{$ i = 1;} - número de inicio de control
"% 04d.jpg" : controle el recuento cero 04 y establezca la extensión de salida .jpg