Script di shell Bash per individuare e rimuovere la sottostringa all'interno di un nome file

2

Sto provando a scrivere uno script di shell bash (che è chiamato da un'azione di Automator) per rinominare gli strappi di TV show DVD che ho chiamato male nel corso degli anni. Voglio rimuovere parte del testo nei nomi dei file. Voglio rimuovere il testo che appare dopo una serie specifica di caratteri che so apparirà sempre nel nome del file. Ma non so quanti personaggi appariranno prima o dopo la serie di personaggi noti. Inoltre, non so se il testo precedente o successivo conterrà più punti o trattini. Un esempio potrebbe probabilmente aiutare:

The.Big.Bang.Theory.S01E01.xxxxxxxx.mp4

So che ogni file conterrà sempre una stringa nel formato di SxxExx dove le x sono sempre numeri. Ma non so quali saranno i numeri. Voglio ottenere il nome file fino a includere la stringa SxxExx e l'estensione del file ma rimuovere tutto il resto. Quindi per l'esempio sopra vorrei finire con:

The.Big.Bang.Theory.S01E01.mp4

Ho provato a utilizzare i comandi di sostituzione delle stringhe incorporati di bash. Ho pensato che il comando expr index mi avrebbe dato il punto di inizio intero della stringa SxxExx e quindi avrei potuto usare $ {nomefile: offset: length} per estrarre solo la parte richiesta del nome file (conosco già l'estensione in modo che possa essere -Aggiunto). Ma sembra che la versione OS di expr non includa la funzionalità di indice. Ho solo script in Basic e LotusScript prima. In quegli ambienti sarebbe stato abbastanza facile usare comandi come 'Mi piace' e 'Istr' o 'Metà'. Ma in fondo non riesco a capirlo. Ho passato ore su google cercando di capire come usare le espressioni regolari per localizzare la sottostringa 'SxxExx' nel nome del file ma non riesco a capirlo. Spero che alcuni sceneggiatori di UNIX intelligenti saranno in grado di aiutarmi!

    
posta Stu 22.08.2011 - 12:27
fonte

2 risposte

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

Come funziona? Il primo ls restituisce l'elenco di file, uno per riga, in questo modo:

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

Quindi perl -nl divide questo in linee, alimentando ciascuna alla regex, proprio come awk *. La regex cattura 3 gruppi (indicati da parentesi), prima il bit prima di SxxEyy, poi quello, quindi il suffisso del file. Quindi assembla semplicemente un comando mv adatto per rinominare i file, in questo modo:

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"

Questo può essere ispezionato e una volta che sei soddisfatto fa quello che vuoi, convogliato in una shell aggiungendo: | sh .

* awk normalmente sarebbe un buon strumento da usare per questo, ma purtroppo solo GNU awk supporta i gruppi di cattura delle espressioni regolari e Mac OS X non include gawk per impostazione predefinita.

    
risposta data 22.08.2011 - 13:21
fonte
3

Solo 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

Rimuovi "echo" quando sei soddisfatto del suo funzionamento.

    
risposta data 22.08.2011 - 14:26
fonte

Leggi altre domande sui tag