2 votos

Bash shell script para localizar y eliminar la subcadena dentro de un nombre de archivo

Estoy tratando de escribir un bash shell script (que es llamado por una Acción de Automator) para renombrar los rips de DVD de programas de TV que he nombrado mal a lo largo de los años. Quiero eliminar parte del texto en los nombres de los archivos. Quiero eliminar el texto que aparece después de una serie específica de caracteres que sé que siempre aparecen en el nombre del archivo. Pero no sé cuántos caracteres aparecerán antes o después de la serie de caracteres conocida. Tampoco sé si el texto anterior o posterior contendrá varios puntos o guiones. Un ejemplo probablemente ayudaría:

The Big Bang Theory S01E01.xxxxxxxx.mp4

Sé que cada archivo contendrá siempre una cadena con el formato SxxExx donde las x son siempre números. Pero no sé cuáles serán los números. Quiero obtener el nombre del archivo hasta la cadena SxxExx y la extensión del archivo, pero eliminar todo lo demás. Así que para el ejemplo anterior terminaría con:

The.Big.Bang.Theory.S01E01.mp4

He intentado utilizar los comandos de sustitución de cadenas incorporados en bash. Pensé que el comando index de expr me daría el punto de inicio entero de la cadena SxxExx y entonces podría usar ${filename:offset:length} para extraer sólo la parte requerida del nombre del archivo (ya conozco la extensión así que se puede volver a añadir). Pero parece que la versión de OS X de expr no incluye la funcionalidad de índice. Sólo he hecho scripts en Basic y LotusScript antes. En esos entornos esto habría sido bastante fácil usando comandos como 'Like' e 'Instr' o 'Mid'. Pero en bash simplemente no puedo entenderlo. He pasado horas buscando en Google tratando de entender cómo utilizar expresiones regulares para localizar la subcadena 'SxxExx' en el nombre del archivo, pero no puedo entenderlo. Espero que algunos scripters UNIX inteligentes sean capaces de ayudarme.

4voto

Mark Puntos 6

Sólo con bash:

for filename in *; do
    if [[ "$filename" =~ (.*S[0-9][0-9]E[0-9][0-9]).*(\....)$ ]]; then
        echo mv "$filename" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
    fi
done

Retira el "eco" cuando estés satisfecho de que funciona.

1voto

Jasmine D Puntos 1
ls | perl -nl -e '/(.*)(S[0-9]+E[0-9]+).*(\.mp4)/ && print "mv \"" . $_ . "\" \"". $1 . $2 . $3 . "\""'

¿Cómo funciona esto? Primero ls produce la lista de archivos, uno por línea, así:

The.Big.Bang.Theory.S01E01.xxxxxxxx.mp4
The.Big.Bang.Theory.S01E02.somecrap.mp4
The.Big.Bang.Theory.S04E12.otherjunk.mp4

Entonces perl -nl divide esto en líneas, alimentando cada una de ellas a la regex, de forma similar a awk*. El regex captura 3 grupos (denotados por paréntesis), primero el bit antes de SxxEyy, luego eso, luego el sufijo del archivo. A continuación, simplemente ensambla un mv comando adecuado para renombrar los archivos, así:

mv "The.Big.Bang.Theory.S01E01.xxxxxxxx.mp4" "The.Big.Bang.Theory.S01E01.mp4"
mv "The.Big.Bang.Theory.S01E02.somecrap.mp4" "The.Big.Bang.Theory.S01E02.mp4"
mv "The.Big.Bang.Theory.S04E12.otherjunk.mp4" "The.Big.Bang.Theory.S04E12.mp4"

Esto se puede inspeccionar y, una vez que esté satisfecho de que hace lo que quiere, se puede canalizar en un shell mediante la adición: | sh .

*awk sería normalmente una buena herramienta para esto, pero lamentablemente sólo GNU awk soporta grupos de captura regex y Mac OS X no incluye gawk por defecto.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X