$ ls *mp3 | xargs mplayer
Playing Lemon.
File not found: 'Lemon'
Playing Tree.mp3.
File not found: 'Tree.mp3'
Exiting... (End of file)
Mein Befehl schlägt fehl, weil die Datei "Lemon Tree.mp3" Leerzeichen enthält und xargs denkt, dass es sich um zwei Dateien handelt. Kann ich find + xargs mit solchen Dateinamen arbeiten lassen?
ls |grep mp3 |sed -n "7p"
können Sie einfach verwendenecho "Lemon Tree.mp3"
.Antworten:
Der
xargs
Befehl verwendet Leerzeichen (Tabulatoren, Leerzeichen, neue Zeilen) als Trennzeichen. Sie können es nur für die neuen Zeilenzeichen ('\ n') mit der folgenden-d
Option eingrenzen:Es funktioniert nur mit GNU xargs. Verwenden Sie für BSD-Systeme die folgende
-0
Option:Diese Methode ist einfacher und funktioniert auch mit den GNU xargs.
quelle
-E
, zum Beispiel:xargs -E '\n'
Das Dienstprogramm xargs liest durch Leerzeichen, Tabulatoren, Zeilenumbrüche und Dateiende getrennte Zeichenfolgen aus der Standardeingabe und führt das Dienstprogramm mit den Zeichenfolgen als Argumente aus.
Sie möchten vermeiden, Leerzeichen als Trennzeichen zu verwenden. Dies kann durch Ändern des Trennzeichens für xargs erfolgen. Nach dem Handbuch:
Sowie:
Um die Frage nach dem Abspielen des siebten MP3 zu beantworten; es ist einfacher zu laufen
quelle
find
und GNUxargs
; Nicht alle Versionen dieser Programme unterstützen diese Optionen (obwohl es einen Fall gibt, dass sie sollten).find
mit-print0
undxargs
mit-0
. AFAIK, HP-UX, AIX und Solaris jedoch nicht (aber ich muss noch korrigiert werden: HP-UX 11i nicht; Solaris 10 nicht; AIX 5.x nicht; aber es handelt sich nicht um aktuelle Versionen ). Es wäre nicht zu ändern hart seinsed
, zum Beispiel ‚Linien‘ mit der Endung zu verwenden ,'\0'
statt'\n'
, und das POSIX 2008getdelim()
würde es einfach zu verwalten.Versuchen
anstatt
quelle
xargs unter MacOS hat keine Option -d, daher verwendet diese Lösung stattdessen -0.
Lassen Sie ls eine Datei pro Zeile ausgeben, übersetzen Sie dann Zeilenumbrüche in Nullen und weisen Sie xargs an, Nullen als Trennzeichen zu verwenden:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
quelle
Dies hat in meinem Fall geholfen, verschiedene Dateien mit Leerzeichen zu löschen. Es sollte auch mit mplayer funktionieren. Der notwendige Trick sind die Anführungszeichen. (Getestet unter Linux Xubuntu 14.04.)
quelle
Dick.Guertins Antwort [1] schlug vor, dass man den Leerzeichen in einem Dateinamen entkommen könnte. Dies ist eine wertvolle Alternative zu anderen hier vorgeschlagenen Lösungen (z. B. die Verwendung eines Nullzeichens als Trennzeichen anstelle von Leerzeichen). Aber es könnte einfacher sein - Sie brauchen nicht wirklich einen einzigartigen Charakter. Sie können die maskierten Leerzeichen einfach direkt hinzufügen lassen:
Darüber hinaus ist das grep nur erforderlich, wenn Sie nur Dateien mit Leerzeichen in den Namen möchten. Allgemeiner (z. B. wenn Sie einen Stapel von Dateien verarbeiten, von denen einige Leerzeichen enthalten, andere nicht), überspringen Sie einfach das grep:
Dann kann der Dateiname natürlich ein anderes Leerzeichen als Leerzeichen haben (z. B. eine Registerkarte):
Dies setzt voraus, dass Sie ein sed haben, das -r (Extended Regex) wie GNU sed oder neuere Versionen von bsd sed unterstützt (z. B. FreeBSD, das ursprünglich die Option "-E" vor FreeBSD 8 geschrieben hat und aus Kompatibilitätsgründen sowohl -r als auch -E unterstützt mindestens durch FreeBSD 11). Andernfalls können Sie einen einfachen Klammerausdruck für Regex-Zeichenklassen verwenden und die Leerzeichen und Tabulatorzeichen manuell in die
[]
Trennzeichen eingeben .[1] Dies ist vielleicht besser als Kommentar oder Bearbeitung dieser Antwort geeignet, aber im Moment habe ich nicht genug Ruf, um Kommentare abzugeben, und kann nur Änderungen vorschlagen. Da die oben genannten Formen (ohne Grep) das Verhalten von Dick.Guertins ursprünglicher Antwort ändern, ist eine direkte Bearbeitung möglicherweise ohnehin nicht angebracht.
quelle
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
Beachten Sie, dass im obigen Befehl für jede Datei ein neuer
xargs
Aufruf erfolgtmplayer
. Dies kann für unerwünschtemplayer
, für andere Ziele jedoch in Ordnung sein.quelle
mplayer
, dass für jede Datei ein neuer Aufruf erfolgt. Es ist wichtig, wenn Sie versuchen, z. B... | xargs -I{} mplayer -shuffle {}
.: Dies wird trotz allem in einer völlig deterministischen Reihenfolge abgespielt-shuffle
.xargs
wird meistens mit Befehlen verwendet, die eine Liste von Dateinamen akzeptieren (einfaches Beispiel :)rm
, und versucht, so viele Dateinamen zu übergeben, wie in jeden Aufruf passen, und wird nur bei Bedarf in mehrere Aufrufe aufgeteilt. Sie können den Unterschied erkennen, wenn Sie einen Befehl verwenden, bei dem jeder Aufruf sichtbar ist, z. B.echo
(Standardeinstellung):seq 0 100000 | xargs
Gibt alle Zahlen von 0 bis 23695 (plattformspezifisch, aber genau das passiert auf meinem System) in der ersten Zeile bis 45539 aus in Zeile 2 usw. Und Sie haben Recht, für die meisten Befehle spielt es keine Rolle.Wenn Sie unter macOS 10.12.x (Sierra) Leerzeichen in Dateinamen oder Unterverzeichnissen haben, können Sie Folgendes verwenden:
quelle
Es hängt davon ab, (a) wie sehr Sie an die Nummer 7 gebunden sind, im Gegensatz zu beispielsweise Zitronen, und (b) ob einer Ihrer Dateinamen Zeilenumbrüche enthält (und ob Sie bereit sind, diese umzubenennen, wenn dies der Fall ist).
Es gibt viele Möglichkeiten, damit umzugehen, aber einige davon sind:
Die
read
Schleife funktioniert nicht, wenn Dateinamen Zeilenumbrüche enthalten. Die anderen funktionieren auch mit Zeilenumbrüchen in den Namen (geschweige denn Leerzeichen) korrekt. Wenn Sie für mein Geld Dateinamen haben, die eine neue Zeile enthalten, sollten Sie die Datei ohne die neue Zeile umbenennen. Die Verwendung der doppelten Anführungszeichen um den Dateinamen ist der Schlüssel für die ordnungsgemäße Funktion der Schleifen.Wenn Sie GNU
find
und GNUxargs
(oder FreeBSD (* BSD?) Oder Mac OS X) haben, können Sie auch die Optionen-print0
und verwenden-0
, wie in:Dies funktioniert unabhängig vom Inhalt des Namens (die einzigen zwei Zeichen, die in einem Dateinamen nicht vorkommen können, sind Schrägstrich und NUL, und der Schrägstrich verursacht keine Probleme in einem Dateipfad, sodass die Verwendung von NUL als Namensbegrenzer alles abdeckt). Wenn Sie jedoch die ersten 6 Einträge herausfiltern müssen, benötigen Sie ein Programm, das mit NUL endende 'Zeilen' anstelle von Zeilenumbrüchen behandelt ... und ich bin mir nicht sicher, ob es welche gibt.
Der erste ist bei weitem der einfachste für den vorliegenden Fall; Es kann jedoch sein, dass es nicht verallgemeinert wird, Ihre anderen Szenarien abzudecken, die Sie noch nicht aufgelistet haben.
quelle
Ich weiß, dass ich die
xargs
Frage nicht direkt beantworte , aber es lohnt sich,find
die-exec
Option zu erwähnen .Gegeben das folgende Dateisystem:
Der Befehl find kann verwendet werden, um den Platz in Dream Theatre und King's X zu verwalten. So finden Sie die Schlagzeuger jeder Band mit grep:
In der
-exec
Option{}
steht für den Dateinamen einschließlich Pfad. Beachten Sie, dass Sie nicht entkommen oder in Anführungszeichen setzen müssen.Der Unterschied zwischen
-exec
den Terminatoren (+
und\;
) besteht darin, dass+
so viele Dateinamen wie möglich in einer Befehlszeile zusammengefasst werden. Während\;
der Befehl für jeden Dateinamen ausführen.Also
find bands/ -type f -exec grep Drums {} +
ergibt sich:und
find bands/ -type f -exec grep Drums {} \;
führt zu:In diesem Fall
grep
hat dies den Nebeneffekt, dass entweder der Dateiname gedruckt wird oder nicht.Natürlich
grep
‚s Optionen-h
und-H
steuert , ob der Dateiname gedruckt wird , unabhängig davon , wiegrep
genannt wird.xargs
xargs
kann auch steuern, wie sich Man-Dateien in der Befehlszeile befinden.xargs
Standardmäßig werden alle Argumente in einer Zeile zusammengefasst. Um das gleiche zu tun, was-exec \;
verwendet wirdxargs -l
. Beachten Sie, dass die-t
Option anweistxargs
, den Befehl zu drucken, bevor er ausgeführt wird.-l
Stellen Sie sicher, dass die Option xargs anweist, grep für jeden Dateinamen auszuführen.Versus der Standardeinstellung (dh keine
-l
Option):xargs
hat eine bessere Kontrolle darüber, wie viele Dateien sich in der Befehlszeile befinden können. Geben Sie der-l
Option die maximale Anzahl von Dateien pro Befehl.Siehe, dass
grep
mit zwei Dateinamen wegen ausgeführt wurde-l2
.quelle
In Anbetracht des spezifischen Titels dieses Beitrags ist hier mein Vorschlag:
Die Idee ist, Leerzeichen in ein eindeutiges Zeichen wie '<' umzuwandeln und dieses dann in '\' zu ändern, einen Backslash gefolgt von einem Leerzeichen. Sie können dies dann in einen beliebigen Befehl einfügen, z. B.:
Der Schlüssel liegt hier in den Befehlen 'tr' und 'sed'; und Sie können jedes Zeichen außer '<' verwenden, z. B. '?' oder sogar ein Tabulatorzeichen.
quelle
tr
? Warum nicht einfachls *.mp3 | sed -n '7!b;s/\([[:space:]]\)/\\\1/g;p'
?Alternative Lösungen können hilfreich sein ...
Sie können mit Perl auch ein Nullzeichen am Ende Ihrer Zeilen einfügen und dann die
-0
Option in xargs verwenden. Im Gegensatz zu den xargs -d '\ n' (in genehmigter Antwort) funktioniert dies überall, einschließlich OS X.Zum Beispiel, um MPEG3-Dateien, die Leerzeichen oder andere lustige Zeichen enthalten können, rekursiv aufzulisten (auszuführen, zu verschieben usw.) - würde ich verwenden:
(Hinweis: Zum Filtern bevorzuge ich die leichter zu merkende "| grep" -Syntax gegenüber den Argumenten "find's" --name.)
quelle