Entiende el código de forma correcta antes de usarlo a tu proyecto y si tdeseas aportar algo puedes comentarlo.
Solución:
for f in *.mp4; do
echo mv "$f"
"$(awk -F '[._]' ' si = sprintf("%02s", substr($5,2));
print $3 "_" $4 "_s" si "e" $1 "." $6 ' <<<"$f")"
done
- Bucles sobre todo
*.mp4
archivos - Cambia el nombre de cada uno al resultado de la
awk
comando, proporcionado a través de la sustitución de comando ($(...)
). - los
awk
El comando divide el nombre del archivo de entrada en tokens por.
o "_" (lo que hace que el primer token esté disponible como$1
el segundo como$2
...). - Primero, el número en "_Snúmero" se rellena a la izquierda a 2 dígitos con un
0
(es decir, un0
solo se antepone si el número aún no tiene 2 dígitos) y se almacena en variablesi
(índice de temporada); si está bien anteponer siempre0
el "programa" awk se puede simplificar a:print $3 "_" $4 "_s0" substr($5,2) "e" $1 "." $6
- El resultado, junto con los tokens restantes, se reorganiza para formar el nombre de archivo deseado.
Nota la echo
antes de mv
para permitirle obtener una vista previa segura del comando resultante, elimínelo para realizar el cambio de nombre real.
Alternativa: un puro bash
solución usando una expresión regular:
for f in *.mp4; do
[[ $f =~ ^([0-9]+)._([^.]+)_S([^.]+).(.+)$ ]]
echo mv "$f"
"$BASH_REMATCH[2]_s0$BASH_REMATCH[3]e$BASH_REMATCH[1].$BASH_REMATCH[4]"
done
- Utiliza el operador de coincidencia de expresiones regulares de bash,
=~
con grupos de captura (las subcadenas en(...)
) para comparar con cada nombre de archivo y extraer subcadenas de interés. - Los resultados coincidentes se almacenan en el especial array variable
$BASH_REMATCH
con elemento0
que contiene todo el partido,1
que contiene lo que coincide con el primer grupo de captura,2
el segundo, y así sucesivamente. - los
mv
el argumento de destino del comando ensambla las coincidencias del grupo de captura en el orden deseado; tenga en cuenta que en este caso, por simplicidad, he hecho el relleno cero desnumber
incondicional - un0
simplemente se antepone.
Como se indicó anteriormente, debe eliminar echo
antes de mv
para realizar el cambio de nombre real.
Una forma común de cambiar el nombre de varios archivos de acuerdo con un patrón es usar el comando Perl rename
. Utiliza expresiones regulares de Perl y es muy potente. Utilizar -n -v
para probar el patrón sin tocar los archivos:
$ rename -n -v 's/^(d+)._(.+)_S2.mp4/$2_s02e$1.mp4/' *.mp4
01._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e01.mp4
02._HORRIBLE_HISTORIES_S2.mp4 renamed as HORRIBLE_HISTORIES_s02e02.mp4
Use paréntesis para capturar cadenas en variables $1
(primera captura), $2
(segunda captura) etc:
^(d+)
capturar números al comienzo del nombre de archivo (en$1)
._(.+)_S2.mp4
capturar todo lo que hay entre._
y_S2.mp4
(dentro$2
)$2_s02e$1.mp4
ensambla tu nuevo nombre de archivo con los datos capturados como quieras
Cuando esté satisfecho con el resultado, elimine -n
desde el comando y cambiará el nombre de todos los archivos de verdad.
rename
suele estar disponible de forma predeterminada en Linux (paquete util-linux
). Hay una discusión similar aquí sobre SO con más detalles sobre cómo encontrar/instalar el comando correcto.
Puedes hacerlo con casi puro bash
(con expansión variable):
for f in *mp4 ; do
newfilename="$f:5:20_s01e$f:1:2.mp4"
echo mv $f $newfilename
done
Si el resultado de este comando se adapta a sus necesidades, puede eliminar el echo
del ciclo, o más simplemente (si su último comando fue el anterior): !! | bash
Aquí puedes ver las comentarios y valoraciones de los usuarios
Recuerda comunicar este artículo si te ayudó.