2016-05-11 19 views
2

Ich habe ein paar Dateien, die falsch benannt sind (mit der Erweiterung zweimal am Ende hinzugefügt). Ich habe versucht, ein Bash-Skript zu schreiben, die das Verzeichnis scannen würde, und benennen Sie sie, aber es wirft einen Fehler aus:Umbenennen von Dateien über Skript

kann nicht ‚/var/random/file/file1.avi.mp4‘ bewegen ‚{/ var/random/file/file1.avi.mp4% .avi.mp4} .mp4' : keine solche Datei oder das Verzeichnis

ich möchte nur richtig die Dateierweiterung umbenennen, und bin nicht sicher, wo der Fehler kommt ins Spiel. Zum Beispiel sollte der obige Fehler eine Dateiendung von .mp4 haben. wenn jemand könnte Unten ist mein Skript, hilft, würde ich in verschuldeten sein ...

#/bin/sh 
for file in $(find /var/random/ -type f -name "*.avi.mp4"); do 
    mv "$file" "{$file%.avi.mp4}.mp4" 
done 
+3

'mv "$ file"„$ {file% .avi.mp4} .mp4 "' – andlrc

+0

Bitte beachten Sie die andere Antwort, die ich nicht gepostet habe, es gibt einige wichtige Änderungen von Code. – andlrc

Antwort

4

Sie haben einen Tippfehler in Ihrer Variable Expansion:

"{$file%.avi.mp4}.mp4" 

sein soll:

"${file%.avi.mp4}.mp4" 

Sie können jedoch einen Blick auf rename (perl-rename)

werfen

wird die Regex die zweite zum letzten Erweiterung in Dateinamen entfernen:

/path/to/file/foo.bar.baz -> /path/to/file/foo.baz 
2
find . -type f -name "*.avi.mp4" -print0 | while read -rd '' filename 
do 
if [ -e "${filename%.avi.mp4}.mp4" ] 
then 
    mv --backup "${filename}" "${filename%.avi.mp4}.mp4" 
    #doing the backup only if the destination file exists to save space. 
else 
    mv "${filename}" "${filename%.avi.mp4}.mp4" 
fi 
done 

Was ist hier passiert:

  1. Wir alle Dateien mit .avi.mp4 Endung find aus.
  2. Da die Datei Zeilenumbrüche enthalten kann, setzen wir die Dateinamen mit print0 der Option find auf Null.
  3. Dieser Ausgang wird in die While-Schleife geleitet, wo wir die Dateien analysieren können.
  4. Einstellung des Trennzeichens -d Option des read auf Null ('') Befehl wir parsen jeden der Null abgeschlossen Dateinamen.
  5. Schließlich verwenden wir Parameter Erweiterung/Substitution, um die .avi.mp4 am Ende jeder Datei loszuwerden und eine .mp4 an jede Datei an der mv Phase anfügen. Siehe Referenz 1.

Referenzen:

  1. Shell parameter expansion
  2. Move manual
  3. Why use while instead of for?
+0

Kannst du bitte darauf eingehen, warum du 'for x in ...' in eine while-Schleife geändert hast und warum '-print0' verwendet wird.Ich denke, OP weiß vielleicht nicht, warum das, was Sie tun, wichtig ist! +1 – andlrc

+0

@andlrc: Im Moment tun. – sjsam

+0

Wir empfehlen '' $ {filename} ''und' "$ {filename% .avi.mp4} .mp4" 'mit doppelten Anführungszeichen um die Namen; das funktioniert sogar mit 'Cute Cat.avi.mp4', während das Auslassen der Anführungszeichen verheerende (oder laute) Fehlermeldungen verursacht - vor allem angesichts der Mühe, die Sie unternommen haben, um sicherzustellen, dass Ihr Code solche Dateinamen im' find ... | während gelesen ... 'code. –