Directorios de cambio de nombre masivos para mover el año de principio a fin

11

Actualmente estoy luchando con algunas carpetas de música. Una vez decidido nombrarlos siguiendo el patrón: artist - album - year. Hoy me di cuenta de que este no era un movimiento inteligente y ahora quiero nombrar a mis directorios siguiendo el patrón: year - artist - albumya que aparecerán en orden ascendente cuando estén en la lista.

Comencé a renombrar a mano pero, con aproximadamente 700 carpetas, tiene que haber una manera más simple; Traté de usar gprenamepero no soy tan bueno en expresiones regulares y bash scripting ...

¿Hay alguien que pueda ayudarme a ahorrar mis pobres dedos?

Algunos ejemplos:

Aes Dana - Memory Shell - 2004 
Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009

se convertiría

2004 - Aes Dana - Memory Shell
2009 - Anja Schneider & GummiHz - Back To Back (Remixes Part 2)

EDITAR: Algunos nombres de artistas y álbumes tienen caracteres especiales como And.Ido Kool & The Gang. Aunque cada directorio tiene -como separador.

TazMayhem
fuente
2
Agregue algunos nombres de directorio de ejemplo y resultados esperados.
Muru
Por ejemplo: Tengo "Aes Dana - Memory Shell - 2004" y me gustaría tener "2004 - Aes Dana - Memory Shell"
TazMayhem
1
Usted sabe cómo editar la pregunta, ¿por qué no agrega eso a la pregunta? Además, ¿alguno de los nombres de álbumes o artistas tiene -en ellos?
Muru
¿El nombre está ordenado por el delimitador "-" por definición, y es posible que aparezca en otra parte del nombre?
Jacob Vlijm
Tiendo a ls las carpetas de origen redirigiendo a un archivo de texto, luego uso vim. Creo una macro para crear un segundo parámetro para cada línea con los componentes relevantes de la carpeta de origen en el orden correcto, luego uso otra macro para poner mv al comienzo de cada línea. Incluso podría ir tan lejos como para tomar una copia de la estructura de carpetas primero en caso de que haya hecho un lío de carpetas / perdido.

Respuestas:

16

Suponiendo que tiene acceso a perl rename(generalmente disponible en Ubuntu, gracias a @Serg por aclarar la diferencia. En caso de duda, llame /usr/bin/renamey debería obtener la correcta), puede usar:

rename -n 's/(.*) - (\d{4})\//$2 - $1/' */

Eliminar -ndespués de la prueba para cambiar el nombre de los directorios. Esto supone que todos los álbumes datan entre 1000 y 9999. Probablemente razonable ...

Explicación

  • s/old/newreemplazar oldconnew
  • (.*)guardar cualquier número de caracteres para referenciarlos más $1tarde
  • (\d{4})\/guarde cuatro dígitos al final de la línea para hacer referencia como $2más adelante.
  • */ hacer coincidir todos los directorios (no los archivos, ¡gracias a @muru por su ayuda!)
Zanna
fuente
3
Quizás lo haga */para que solo coincidan los directorios.
Muru
@muru parece que no funciona! ¿Qué estoy haciendo estúpidamente?
Zanna
1
@Zanna creo que a lo que se refieren es al hecho de que algunos shells como mkshtienen una llamada incorporada rename. Es suficiente reemplazarlo con la ruta completa o llamar prenamepara llamar al cambio de nombre de Perl
Sergiy Kolodyazhnyy
1
@Zanna encontró este bit interesante: unix.stackexchange.com/a/229248/85039 TL; DR : El rename"a veces no se llama prename" pero aparentemente son dos "ramas" del mismo script, una que no se mantiene por Debian, y el otro que es. Así que sí . . . es todo un desastre: algunos proyectiles tienen el suyo rename, el paquete perl tiene el suyo rename, y Debian proporciona un paquete separado
Sergiy Kolodyazhnyy
1
@Zanna Estaba pensando en el programa mencionado rename.ulen unix.stackexchange.com/q/229230/21167
zwol
6

El script simple de Python puede hacer ese trabajo:

$ tree
.
├── Aes Dana - Memory Shell - 2004
├── Anja Schneider & GummiHz - Back To Back (Remixes Part 2) - 2009
└── rename_dirs.py

2 directories, 1 file
$ ./rename_dirs.py */
$ tree
.
├── 2004 - Aes Dana  -  Memory Shell 
├── 2009 - Anja Schneider & GummiHz  -  Back To Back (Remixes Part 2) 
└── rename_dirs.py

Contenido del guión:

#!/usr/bin/env python
from shutil import move;
import sys

for i in sys.argv[1:] :
    parts = i[:-1].split('-')
    year = parts[-1].strip()
    new_name = year + " - " + " - ".join(parts[:-1]).strip()
    move(i,new_name)

Cómo funciona esto:

  • El truco principal es que ejecutamos script desde el mismo directorio donde residen los objetivos. También pasamos */a proporcionar solo directorios como argumentos para el script
  • El script itera sobre todos los argumentos de la línea de comandos, desglosando cada nombre de archivo en una lista de cadenas en el -carácter. El nuevo nombre de archivo se construye a partir de partes que extrajimos.
  • move()función del shutilsmódulo es lo que realmente cambia el nombre de los directorios

Tenga en cuenta el uso: ./rename_dirs.py */

Sergiy Kolodyazhnyy
fuente