Tengo una carpeta que tiene varios cientos de miles de archivos llamados "ABC 123456". Necesito agregar un guión entre los dos bloques de texto como este "ABC - 123456". Dejando el espacio final.
Automator no ofrece un método para contar 4 caracteres e insertar un nuevo guión y espacio.
Tengo este comando de terminal y he estado jugando con él.
for file in *.txt
do
echo mv "$file" **"$file" count 3 "- "**
done
¿Alguien sabe de un Applescript o puede ayudar con el comando de terminal que me ayudará a cambiar el nombre de los archivos?
La pregunta en sí tampoco es exacta, porque el OP habla de:
ABC 123456
(sin extensión), pero en el código de ejemplo usando *.txt
extensiónABC - 123456
, pero en el próximo paso sobre counting to 4
y count 3
, p ABCD 12
.AB 345
El problema es divisible en 3 partes separadas:
Anuncio "seleccionando los archivos correctos". Algunas utilidades externas pueden seleccionar los archivos, por ejemplo, con el find
comando. Los principales beneficios de la find
son:
man find
.)Anuncio "preparar el nuevo nombre". Esto se puede hacer con programas externos, como sed
o awk
cualquier programa que pueda manipular texto en scripts de shell, o se puede hacer (en algunos casos simples como este) dentro del bash
mismo, y es posible ahorrar una costosa ejecución de comando. (para cientos de miles de archivos hace la diferencia).
La siguiente:
${file/ /-}
sustituye (reemplaza) un espacio (la / /
parte) con el guión ( /-
). Entonces es posible escribir
mv "$file" "${file/ /-}"
y guardar la sed
ejecución.
Así que una de las alternativas de solución podría ser , por ejemplo, la siguiente:
#!/bin/bash
while IFS= read -r -d $'\0' filename
do
newfilename="${filename/ /-}"
[[ "$filename" != "$newfilename" ]] && echo mv -i "$filename" "$newfilename"
done < <(find . -maxdepth 1 -type f -iname "* *.jpg" -print0)
Lo anterior es para DRY RUN : solo mostrará lo que se hará, para la ejecución real, elimine el archivo echo
.
Descomposición:
seleccionando los archivos correctos para el cambio de nombre: encontrará find . -maxdepth 1 -type f -iname "* *.jpg" -print0
todos
-maxdepth 1
)-type f
)-print0
)el ciclowhile IFS= read -r -d $'\0' filename; do ... done < <( )
find
comando anterior-d $'\0'
)-r
) /tema avanzado - no es necesario explicarlo aquí/IFS=
el recorte de los espacios en blanco iniciales y finales del nombre del archivo (también, un tema un poco avanzado)preparando el nuevo nombre de archivonewfilename="${filename/ /-}"
bash
internamente (sin ejecutar un comando externo).${filename/ /- }
el cambio de nombre real se realiza mediante el mv
comando (ver man mv
desde la terminal), donde
-i
que le preguntará al usuario si aquí ya hay un archivo con el nuevo nombre de archivo (no lo anule)y the mv
se ejecuta solo cuando the newfilename
es diferente de thefilename
[[ "$filename" != "$newfilename" ]]
La solución anterior es en su mayoría propensa a errores, pero aún no es muy efectiva, porque para cientos de miles de archivos se ejecutará cientos de miles de veces el mv
comando. La solución puede ser: usar alguna utilidad, que pueda leer los nombres de los archivos y hacer el cambio de nombre sin ejecutar el mv
comando N veces. Por ejemplo, el "gran arma" de los administradores del sistema es el "perl", como:
find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
perl -0nle '$n=$_; $n=~s/ /-/; rename $_,$n unless($_ eq $n || -e $n)'
lo que cambiará el nombre de todos los archivos que genera la ejecución find
en una sola ejecución, por ejemplo, mucho más rápido que miles de mv
ejecuciones.
Las pruebas Tor (DRY RUN) utilizan lo siguiente:
find . -maxdepth 1 -type f -iname "*.jpg" -print0 |\
perl -0nle '$n=$_; $n=~s/ /-/; print qq{old:$_ new:$n\n} unless($_ eq $n || -e $n)' #print instead of the rename
Ps: el perl es lo suficientemente potente como para manejar todo por sí mismo, por ejemplo. el comando de búsqueda también, pero es un tema más avanzado...
Ps2: mi inglés es mucho peor que mi bash
, por lo que alguien podría editar esta publicación para agregar/corregir cosas... ;)
Si los nombres de sus archivos son "ABC 123456" con un solo espacio entre los 3 primeros y los siguientes, entonces está tratando de reemplazar el espacio con un carácter (o un guión o algo así), para que se vea como ABC-123456.
Encontré este artículo que explica cómo hacerlo.
Ejemplo:
Tenga en cuenta que el siguiente comando solo reemplazará los espacios con guiones. Si necesita una sustitución diferente, deberá modificar el comando en consecuencia.
for i in *.JPG; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done
Otros:
Si quisiera guiones bajos o cualquier otro carácter en lugar de un guión, simplemente cambiaría la s, ,-,g
parte del comando anterior a s, ,_,g
.
Para saber cómo ver este artículo .
Aquí hay una prueba en mi MBA 10.9.5 (utilicé un archivo ABC 123456.png) y lo coloqué en una nueva carpeta. Entonces hice el cd a ese directorio en Terminal y ejecuté
for i in *.png; do mv "$i" "`echo $i | sed -e 's, ,-,g'`"; done
El resultado es que funciona muy bien (cambia el nombre del archivo)
Cómo funciona: reemplazaría el espacio en el nombre del archivo en todos los archivos *.png en esa carpeta, así que asegúrese de tenerlo primero en la carpeta correcta.