Insertar carácter en el cambio de nombre de la carpeta por lotes

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?

Respuestas (2)

La pregunta en sí tampoco es exacta, porque el OP habla de:

  • nombres de archivos como ABC 123456(sin extensión), pero en el código de ejemplo usando *.txtextensión
  • agregue un guión entre dos bloques (p. ej., ¿dónde está el espacio) como ABC - 123456, pero en el próximo paso sobre counting to 4y count 3, p ABCD 12.AB 345
  • también, quiero mantener el espacio final, lo que es extraño, pero está bien;)

El problema es divisible en 3 partes separadas:

  1. seleccionando los archivos correctos para el cambio de nombre
  2. preparando el nuevo nombre de archivo, reemplazando/agregando caracteres al antiguo
  3. el cambio de nombre "físico"

Anuncio "seleccionando los archivos correctos". Algunas utilidades externas pueden seleccionar los archivos, por ejemplo, con el findcomando. Los principales beneficios de la findson:

  • también puede buscar archivos recursivamente en los subdirectorios
  • Es posible seleccionar con mayor precisión los archivos correctos, por ejemplo, excluir directorios, seleccionar archivos por tiempo o tamaño, etc. (consultar desde la terminal man find.)

Anuncio "preparar el nuevo nombre". Esto se puede hacer con programas externos, como sedo awkcualquier programa que pueda manipular texto en scripts de shell, o se puede hacer (en algunos casos simples como este) dentro del bashmismo, 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 sedejecució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" -print0todos

    • lo que están solo en el directorio actual ( -maxdepth 1)
    • y son archivos simples ( -type f)
    • y su nombre coincide con (cualquier cosa) (espacio) (cualquier cosa). jpg mayúsculas y minúsculas, por ejemplo, el nombre debe contener un espacio
    • proporcione los nombres de archivo como terminados en nulo , por lo que su nombre también puede contener de forma segura el carácter de nueva línea. ( -print0)
  • el ciclowhile IFS= read -r -d $'\0' filename; do ... done < <( )

    • lee la salida del findcomando anterior
    • donde los nombres de archivo terminan en nulo ( -d $'\0')
    • ignore cualquier carácter escapado ( -r) /tema avanzado - no es necesario explicarlo aquí/
    • evita 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/ /-}"

    • se realiza bashinternamente (sin ejecutar un comando externo).
    • si desea preservar el espacio final después del uso del guión${filename/ /- }
  • el cambio de nombre real se realiza mediante el mvcomando (ver man mvdesde la terminal), donde

    • lo -ique le preguntará al usuario si aquí ya hay un archivo con el nuevo nombre de archivo (no lo anule)
  • y the mvse ejecuta solo cuando the newfilenamees 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 mvcomando. 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 mvcomando 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 finden una sola ejecución, por ejemplo, mucho más rápido que miles de mvejecuciones.

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, ,-,gparte 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.

renombrado