Usted va a ejecutar en algunos problemas si desea cambiar el nombre de archivos y directorios al mismo tiempo. Renombrar solo un archivo es bastante fácil. Pero desea asegurarse de que los directorios también cambien de nombre. No puede simplemente mv Motörhead/Encöding Motorhead/Encoding
ya Motorhead
que no existirá en el momento de la llamada.
Por lo tanto, necesitamos un recorrido profundo de todos los archivos y carpetas, y luego cambiar el nombre del archivo o carpeta actual solamente. Lo siguiente funciona con GNU find
y Bash 4.2.42 en mi OS X.
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
Puede cambiar la expresión regular utilizando new="${f//[\\\/\:\*\?\"<>|]/}"
si desea reemplazar algo que Windows no puede manejar.
Guarde este script como rename.sh
, hágalo ejecutable con chmod +x rename.sh
. Entonces, llámalo como rename.sh /some/path
.
Asegúrese de resolver cualquier colisión de nombre de archivo (" Notice
" anuncios).
Si está absolutamente seguro de que realiza los reemplazos correctos, elimine echo
el script para cambiar el nombre de las cosas en lugar de simplemente imprimir lo que hace.
Para estar seguro, recomendaría probar esto en un pequeño subconjunto de archivos primero.
Opciones explicadas
Para explicar lo que sucede aquí:
-depth
asegurará que los directorios se recreen primero en profundidad, para que podamos "enrollar" todo desde el final. Por lo general, find
atraviesa de manera diferente (pero no primero).
-print0
garantiza que la find
salida esté delimitada por nulos, de modo que podamos leerla read -d ''
en la file
variable. Hacerlo nos ayuda a lidiar con todo tipo de nombres de archivos extraños, incluidos los que tienen espacios e incluso nuevas líneas.
- Obtendremos el directorio del archivo con
dirname
. No olvides citar siempre tus variables correctamente, de lo contrario, cualquier ruta con espacios o caracteres globales rompería este script.
- Obtendremos el nombre de archivo real (o el nombre del directorio) con
basename
.
- Luego, eliminamos cualquier carácter no válido del
$f
uso de las capacidades de reemplazo de cadenas de Bash. Inválido significa cualquier cosa que no sea una letra mayúscula o minúscula, un dígito, una barra diagonal ( \/
), un punto ( \.
), un guión bajo o un guión negativo.
- Si
$f
ya está limpio (el nombre limpio es idéntico al nombre actual), omítalo.
- Si
$new
ya existe en el directorio $d
(por ejemplo, tiene archivos nombrados resume
y résumé
en el mismo directorio), emita una advertencia. No desea cambiarle el nombre porque, en algunos sistemas, mv foo foo
causa un problema. De otra manera,
- Finalmente cambiamos el nombre del archivo original (o directorio) a su nuevo nombre
Como esto solo actuará en la jerarquía más profunda, el cambio Motörhead/Encöding
de nombre Motorhead/Encoding
se realiza en dos pasos:
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
Esto garantiza que todos los reemplazos se realicen en el orden correcto.
Archivos de ejemplo y prueba de funcionamiento
Asumamos algunos archivos en una carpeta base llamada test
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
Aquí está el resultado de una ejecución en modo de depuración (con el echo
frente de la mv
), es decir, los comandos que se llamarían y las advertencias de colisión:
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
Nótese la ausencia de mensajes para with-hyphen.txt
, schedule
y test
en sí.
mv
ya existe el destino , lo que puede suceder (1) si tiene archivos que ya están limpios (lo que resulta enmv foo foo
), o (2) si tiene archivos con el mismo nombre excepto para los caracteres especiales (por ejemplo,mv Encöding Encoding
donde ya tiene unEncoding
archivo además deEncöding
).Sé que no es exactamente lo que querías, pero si conoces la codificación original, quizás puedas usarla
convmv
para cambiar la codificación a UTF-8, lo que debería solucionar la mayoría de los problemas.Esto funcionó para mí en una carpeta con algunos nombres de archivo polacos codificados no válidos:
Tenga en cuenta que este comando en realidad no cambia el nombre de nada; Añadir
--notest
opción para realmente cambiar el nombre de los archivos.fuente
convmv
opción es increíblemente simple y perfecta. Para OP, que tiene una multitud potencial de conjuntos de caracteres, esto podría combinarse con la otra respuesta, ya queconvmv
parece saber cuándo o cuándo no encuentra el formato correcto. Al recorrer los charsets, víaconvmv --list
, uno los codificaría correctamente.convmv -t utf8 --nfc -f iso-8859-1 --notest -r .
---nfc
Debía conformarme con Linux antes que OS X más o menos, simplemente escribirconvmv
da las opciones (útiles).Lo sé, preguntaste por renombrar.
Pero puede esquivar el problema con bastante facilidad utilizando software como MusicBrainz Picard .
Es capaz de identificar música (huellas digitales de audio), descargar todos los datos necesarios (incluidas las imágenes de portada, donde estén disponibles) de la enorme base de datos MusicBrainz y mover los archivos para que su colección se ajuste a cualquier patrón que desee. Lo uso durante años y siempre funcionó perfectamente con cualquier cosa, desde cirílico hasta árabe; y por supuesto (al menos para los scripts basados en latín) también puede hacer la conversión a ASCII.
Con este enfoque, realmente no importa cuán desordenado / mal nombrado esté realmente su colección, siempre que los archivos sean legibles y completos.
(¿Mencioné que es gratis? ¿Tanto en la libertad de expresión como en la cerveza gratis? ¿Tanto el software como la base de datos ...?)
fuente