Tengo un script bash que cambia el nombre de los archivos en una carpeta según la entrada del símbolo del sistema:
echo "Please rename and press enter" read rename
if [ -z "$rename" ]; then
printf "no caption was selected, aborting!\n"
exit 1
fi
printf "rename is $rename\n" count=1
for i in *.jpg; do
j=printf "%04d" $count
j="$rename"$j".jpg"
count=$((count + 1))
mv "$i" $j
done
fi
shift
done
¿Cómo puedo modificar este script para que los archivos de la carpeta cambien de nombre según su tamaño?
Si ordeno los archivos según el tamaño, se verán así en la carpeta:
a009 978kb
a001 567kb
a003 499kb
a008 432kb
Entonces quiero que se cambie el nombre de los archivos resultantes:
a001 978kb
a002 567kb
a003 499kb
a004 432kb
Respuesta1
Algo como esto:
echo "Please rename and press enter"
read rename
ls |
# prepend filename with file size in bytes
parallel stat -c %s,,sep,,%n -- |
# sort by number
sort -n |
# rename to sequencenumber followed by size in bytes
parallel -q --colsep ,,sep,, mv {2} "$rename"{#}_{1}
Respuesta2
El truco principal es reemplazar
for i in *.jpg
con
for i in $(ls -S *.jpg)
sin embargo, como señaló Kusalananda, esto supone nombres de archivos "educados" (sin espacios, sin caracteres de control), por lo que aquí hay un enfoque diferente:
count=1
ls -S --escape *.jpg | while read f; do
n=$(printf "%04d" $count)
((count++))
mv --no-clobber "$f" "$rename$n.jpg"
done
-S
ordena disminuyendo el tamaño del archivo
--escape
evita que los nombres con nuevas líneas incrustadas causen daños
--no-clobber
evita que se sobrescriban los archivos de destino en caso de que el script se ejecute dos veces
PD: La respuesta de Ole Tange es una forma muy agradable y eficiente de hacer lo mismo, pero probablemente no verá la diferencia a menos que cambie el nombre de miles de archivos de forma rutinaria.
Respuesta3
En el zsh
caparazón:
typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
count=$(( count + 1 ))
mv -i -- "$name" "a$count.jpg"
done
Esto iteraría sobre todos los archivos normales con un .jpg
sufijo de nombre de archivo en el directorio actual, en orden de mayor a menor. Para cada archivo, le cambiaría el nombre a aNNN.jpg
donde NNN
está el recuento entero lleno de ceros de los archivos procesados hasta el momento.
El (.DNOL)
calificador global ordena los nombres de archivos coincidentes en el orden correcto usando OL
("orden inverso por longitud") y selecciona solo archivos normales (incluidos nombres ocultos) usando .D
("archivos normales y archivos de puntos"). Esto N
hace que el patrón se expanda a nada si no hay ningún nombre coincidente ("glob nulo").
Esto funcionaría con todos los nombres de archivos válidos en cualquier sistema Unix que tenga zsh
instalado.
Para usar esto desde bash
:
zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
count=$(( count + 1 ))
mv -i -- "$name" "a$count.jpg"
done'
Si tiene una variable $rename
que desea pasar como prefijo de nombre de archivo en lugar de usar a
:
zsh -c 'typeset -Z 3 count=0
for name in *.jpg(.DNOL); do
count=$(( count + 1 ))
mv -i -- "$name" "$1$count.jpg"
done' zsh "$rename"
Tenga en cuenta que zsh
en la última línea no es un error tipográfico y que el valor de $rename
se utiliza $1
dentro del zsh -c
script.