Come rimuovere i caratteri finali nei nomi dei file in Bash?


13

Ho un sacco di file multimediali come quelli qui sotto:

tvshow.s01e11]Bloodlines.avi
tvshow.s01e12]suffer.avi
tvshow.s01e13]NotMe.avi

Vorrei rinominarli

tvshow.s01e11.avi
tvshow.s01e12.avi
tvshow.s01e13.avi

Ho provato a usare la ridenominazione ma evidentemente non riesco a ottenere la sintassi giusta perché non riesce.


Se mai vuoi farlo in una GUI, krenameè adorabile. Ha ogni sorta di potenti opzioni e ti mostra cosa farà prima di farlo. Potresti anche usarlo per testare modelli che potresti usare in bash in seguito.
Joe,

Risposte:



14

Nella shell, si potrebbe fare semplicemente:

for x in *]*.avi ; do 
    mv -i "$x" "${x%]*.avi}.avi"
done

La shell può produrre un elenco di nomi di file con solo un normale globo e ${var%pattern}rimuove il modello di corrispondenza (più breve) dalla fine della stringa in variabile var. Poiché l'estensione finale è sempre .avi, l'ho appena rimossa con il motivo e l'ho aggiunta di nuovo. Con le virgolette, questo dovrebbe funzionare anche con nomi di file contenenti spazi, comeFancy Name for a Show.s01e01]Asdf.avi


@NoviceC il modello extglob non era una cattiva idea. In realtà, qualcosa come ${x/]*([^.])}dovrebbe fare, rimuove una parentesi e qualsiasi numero di non punti. (anche se fallisce se ci sono altre parentesi o punti, poiché non è bloccato fino alla fine della stringa)
ilkkachu,

È un buon punto. Ma ho davvero complicato troppo il problema quando avrei dovuto andare ${x/]*.avi}e ho appena aggiunto un .avisimile a te. Ma non ero anche soddisfatto di come si sarebbero spezzati gli spazi nel nome (`find . -name '*]*.avi'`). Sono stato felice di fornire un metodo di comando unix standard limitato, dal momento che la ridenominazione non lo è, ma questo fa esplodere il mio.
Principiante C,

2

Tutto ciò è poco pratico - le altre risposte sono molto più veloci e più brevi - ma ...

Puoi usare PowerShell! Di recente Microsoft lo ha open-source e l'ha reso multipiattaforma. Per i download e le istruzioni di installazione per il tuo sistema operativo, consulta la sezione "Ottieni PowerShell" .

Una volta installato, puoi usare questo breve script:

Get-ChildItem -File '*]*.avi' | ForEach-Object {
    Rename-Item $_ -NewName (($_.Name -Split ']')[0] + '.avi')
}

Fondamentalmente, attraversa ogni oggetto nella directory corrente che corrisponde a un file *]*.avi, ottiene la parte prima della parentesi, la .aviricollega su di essa e la assegna come nuovo nome.

Per eseguirlo direttamente da Bash, utilizzare questo one-liner semi-golfato:

powershell -command $'gci -File \'*]*.avi\'|%{rename-item $_ -NewName (($_.Name -Split \']\')[0]+\'.avi\')}'

Citazione in fuga per gentile concessione di questa risposta Stack Overflow .

(Testato in Bash su Ubuntu su Windows. Probabilmente c'è un modo molto più breve di farlo con PowerShell, ma volevo mostrare qualcosa che è comprensibile per le persone che non conoscono le espressioni regolari.)


Rube Goldberg sarebbe orgoglioso! I regex sono un vero PITA da imparare, ma ne valgono la pena molte volte - anche a livello rudimentale sono in grado di usarli.
Joe,

1

Debian ha un pacchetto chiamato mmv che potrebbe anche essere disponibile in altre distribuzioni, e in caso contrario dovrebbe essere abbastanza facile da compilare dal sorgente. Ti permette di scrivere questo:

mmv '*]*.avi' '#1.avi'

Puoi leggere la pagina man di Ubuntu per questo comando per maggiori dettagli.


0

Questo cercherà il modello e sostituirà il testo usando sed.

 $sed 's/\(.*]\)[a-zA-z0-9].*\(.avi\)/\1\2/' filename
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.