Ich habe kürzlich alle meine FLAC-Dateien mit XLD auf meinem Mac OS 10.7 (Lion) auf eine niedrigere Abtastrate von 44,1 kHz und eine Bittiefe von 24 Bit konvertiert (da iPhone / iPod darüber hinaus nichts unterstützen).
Obwohl ich XLD anwies, alle vorherigen Dateien zu überschreiben, fügte XLD (1)
am Ende einer Datei wie von ein
some_song.m4a
zu
some_song(1).m4a
Jetzt möchte ich das (1)
von allen FLAC-Dateien entfernen, die ich konvertiert habe.
Ich weiß, ich hätte wahrscheinlich ein Programm oder sogar ein AppleScript verwenden können, um die Dateien umzubenennen, aber ich wollte lernen, wie man die alte Kommandozeile benutzt.
Ich weiß, dass find . -name *\(1\).m4a
alle konvertierten FLAC-Datei greifen wird.
Als nächstes weiß ich, dass ich etwas mit den gefundenen Dateien anfangen -exec
und mv
sie umbenennen muss. Aber was ich nicht herausfinden kann, ist, wie man den ursprünglichen Dateinamen behält und nur den entfernt (1)
.
Möglicherweise muss ich eine Gruppen-Regex-Erfassung durchführen, um den Teil des Dateinamens zu speichern, den ich nicht ändern möchte? Oder vielleicht ist es nicht möglich, alles in einer Zeile zu tun, und ich sollte ein Shell-Skript erstellen (was ich nicht so gerne mache, aber ich bin bereit, es zu versuchen).
Irgendwelche Tipps oder Vorschläge sind willkommen! Vielen Dank!
find
), die möglicherweise Ihr eigentliches Problem löst (Konvertieren von Audiodateien), sind Sie möglicherweise an einem Blick auf audiotools.sourceforge.net und auf diesen Beispielfall (für macosx lion) invibe.net/ interessiert. LaurentPerrinet / SciBlog / 2012-04-22Antworten:
Versuchen Sie nicht, die
find
Ausgabe zu analysieren, außer als letztes Mittel. Es ist wichtig zu wissen, dass Dateinamen auf Unix-Dateisystemen keine Strings sind (ein weit verbreitetes Missverständnis), sondern binäre Blobs, die alle Zeichen außer/
dem Null-Zeichen enthalten können. Das sichere und korrekte Parsen von Dateinamen ist eine Qual, die Sie in 99% der Fälle nur vermeiden möchten (sehen Sie sich nur an, wie haarig dersed
Ausdruck in @ yareks Antwort ist und selbst das deckt nicht alle Fälle ab). . Zum Glück gibt es in diesem Fall einen viel einfacheren Ansatz:quelle
done
?sed
Rohransatz ist, dass dies viel sicherer ist. Es ist immer noch einfacher zu lesen als Regex-Backslash-Suppe, vorausgesetzt, Sie verstehen einige grundlegende Shell-Skriptkonstrukte.$arg
Variable erleichtert das Lesen erheblich.find
Aufrufsh
mit ziemlich portable POSIX - Syntax. Weitere Informationen finden Sie im Abschnitt zur Parametererweiterung , im Abschnitt zu zusammengesetzten Befehlen zur Erläuterung derfor
Schleife und in der POSIX-find
Spezifikation . Zusätzlich zu diesen Ressourcen beantworte ich gerne Ihre spezifischen Fragen.Unter Debian und Ubuntu kann ich
rename 's/\(1\)//' *.m4a
Ihr Problem lösen.quelle
man rename
, aber ich habe eigentlich nichtrename
:-bash: rename: command not found
(which rename
zeigt nichts).man -a rename
findet Umbenennungs (2) - die syscall und Umbenennungs (n) - den TCL - Befehl. Es gibt dort weder umbenennen (1) noch das Dienstprogramm selbst.rename
ist ein Perl-Skript, das in den Beispielen einiger Perl-Installationen enthalten ist, und einige Distributionen fügen es in den Pfad ein, weil es ein praktischer Befehl ist. (@ Hobbes vielleicht finden Sie es im Internet)rename
ist normal binär (nicht Perl). Eine weitere Einschränkung ist jedoch, dass nicht alle Versionen derrename
Unterstützung reguläre Ausdrücke unterstützen. Die Version, die ich zum Beispiel habe, erlaubt nur das direkte Ersetzen von Strings, zBrename '(1)' '' *.m4a
rename
Skript wird nur von Debian und Derivaten installiert. Andere Linux-Systeme haben ein anderesrename
Dienstprogramm (von Patrick gezeigt). OSX hat keine.In zsh mit zmv :
In dem zweiten Argument (der neue Name),
$1
und$2
beziehen sich auf die eingeklammerten Gruppen(PATTERN)
in dem Quellenmuster. Eine andere Art, diese Umbenennung zu schreiben, istquelle
Der folgende Ansatz gibt Ihnen die Möglichkeit, die generierten Befehle vor dem Ausführen in der Vorschau anzuzeigen / zu bereinigen. Er ist sehr portabel: Er sollte nicht nur auf einem Mac funktionieren, nicht nur mit bash und nicht nur mit GNU sed. Selbst auf Systemen ohne
find
(1) Befehl ist es problemlos möglich, sie durchdu
(1) zu ersetzen .Wenn Sie mit den gedruckten Befehlen zufrieden sind, führen Sie sie mit
| sh -x
angehängten Befehlen erneut aus .Wenn Sie sich Gedanken über Leerzeichen in Dateinamen machen, fügen Sie ein weiteres s hinzu , um alle Leerzeichen zu umgehen:
Wenn andere Sonderzeichen erwartet werden, wird es ein bisschen kniffliger:
Die erste Funktion wandelt alles
'
in eine Form um, die in der Mitte eines'...'
Strings wörtlich genommen wird . Die zweite Funktion generiert mv- Befehle, deren Argumente in eingeschlossen sind'...'
.quelle
(
und alle anderen Sonderzeichen) nicht und setzt den Dateinamen nicht in Anführungszeichen. Ich habe versucht, Ihren Befehl zu ändern, konnte aber nicht herausfinden, wie Anführungszeichen um beide Dateinamen für denmv
Befehl eingefügt werden . Eine der resultierenden Ausgaben Ihres Befehls istmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. Und wenn ich diesen Befehl ausführe, bekomme ich-bash: syntax error near unexpected token '('
.e
Befehl nach dem Ersetzen hinzufügt . Zum Beispielfind . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
wird der Befehl ausgeführt, ohne eine Weiterleitung ansh -x
.Hier ist ein kleines Skript, das das macht:
quelle
`find ...`