¿Secuencia de comandos para cambiar el nombre del archivo por lotes intercambiando subcadenas en el nombre del archivo?

¿Secuencia de comandos para cambiar el nombre del archivo por lotes intercambiando subcadenas en el nombre del archivo?

Tengo un grupo de archivos llamados comotítulo_diciembre_palabra1_palabra2.pngy desea iterar a través del directorio e intercambiar word1y word2dentro de cada archivo.

es decir, ir desde button_december_state_pressed.png->button_december_pressed_state.png

¿Alguna sugerencia sobre cómo podría lograr esto?

La mayoría de los programas por lotes que he encontrado para OS X no pueden especificar un carácter para dividir las palabras y esperaba que alguien pudiera ayudarme con un script rápido para resolver esto.

Respuesta1

En bash, se puede hacer de la siguiente manera:

  for i in *; do echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3 }' ; done

Este comando primero encuentra todos los archivos en el directorio actual, luego proporciona estos nombres (se suponesin comprobarque hay tres guiones bajos y un . en estos nombres de archivos) a awk, que los reorganiza en el orden que desee.

La única parte complicada es que -F'[_.]'la opción -F' 'se utiliza para identificar el delimitador entre diferentes campos, y en este último caso el delimitador toma su valor predeterminado, un espacio. Pero la opción -F'[_.]'define una clase de caracteres de elementos intercambiables, en este caso guión bajo y punto, que pueden usarse a voluntad como delimitadores.

Editar:

Bien, ya que esto funciona, sin mover nada, ahora podemos implementar el acto real de cambiar el nombre de los archivos:

  for i in *; do ni=$(echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3"."$5 }') && mv "$i" "$ni" ; done

Respuesta2

Zsh yzmv

Si tienes zsh (que viene por defecto en OS X) puedes usarzmv:

% zsh
% autoload -U zmv
% zmv 'title_december_(*)_(*).png' 'title_december_$2_$1.png'

Ejecutaría el siguiente comando (úselo zmv -npara hacer un ensayo sin cambiar el nombre):

mv -- title_december_word1_word2.png title_december_word2_word1.png

Obviamente puedes ser un poco más flexible si las primeras partes son diferentes por imagen:

% zmv '(*)_(*)_(*).png' '$1_$3_$2.png' 
mv -- foo_bar_word1_word2.png foo_bar_word2_word1.png
mv -- title_december_word1_word2.png title_december_word2_word1.png

Esto funciona porque las coincidencias son codiciosas y, por lo tanto, se tragan todos los guiones bajos hasta el último antes de los otros grupos de coincidencias.


estilo Perlrename

En OS X puedes obtenerrenameconcerveza casera:

$ rename -n 's/(.*)_(.*)_(.*).png/$1_$3_$2.png/' *
'foo_bar_word1_word2.png' would be renamed to 'foo_bar_word2_word1.png'
'title_december_word1_word2.png' would be renamed to 'title_december_word2_word1.png'

La -nopción solo imprime lo que se habría cambiado de nombre.

información relacionada