Wie führe ich find mit GNU xargs aus, um eine Reihe von Verzeichnissen zu durchlaufen?

737
wilhelmtell
$ echo .h d e.h |xargs -IA find A -name '*.h' find: `a.h b.h c.h d e.h': No such file or directory $ echo -e a.h\\nb.h c.h d e.h |xargs -IA find A -name '*.h' a.h find: `b.h c.h d e.h': No such file or directory 

Das Problem ist, dass -Ixargs davon ausgeht, dass Argumente durch Zeilenumbrüche begrenzt werden. Ich bin nicht sicher, warum das so ist. Ich glaube, ich kann dieses Problem mit sed lösen, aber ich frage mich, ob es einen Trick oder eine Redewendung von xargs gibt, mit der ich nicht vertraut bin.

Ich suche nach einer Lösung, die auch unter OS X funktioniert. Unter OS X scheint der Schalter xargs -J gut zu funktionieren. Die Manpage behauptet, dass dieser Schalter nur kontrolliert, wo die Argumente für die ausführbare Datei platziert werden - was genau das ist, was ich will.

0

4 Antworten auf die Frage

0
quack quixote

Hmm. Haben Sie brauchen das Rohr und xargs? Es scheint, als ob all Ihr Beispiel wirklich das findund das braucht echo.

Ich vermute, dies ist ein Teil eines größeren Puzzles, daher funktioniert es möglicherweise nicht im Zusammenhang mit dem, was Sie tun, aber Ihr Beispiel könnte folgendermaßen aussehen:

$ find `echo .h d e.h` -name '*.h'  $ find $(echo .h d e.h) -name '*.h' 

... was auf meinem System dazu führt find, jedes Argument einzeln zu prüfen:

find: `a.h': No such file or directory find: `b.h': No such file or directory find: `c.h': No such file or directory find: `d': No such file or directory find: `e.h': No such file or directory 

Ich habe keine OSX-Maschine zum Testen, und diese können bash-spezifisch sein.

Meine ursprüngliche Absicht war es, eine Liste der Verzeichnisse und Dateien von stdin zu haben. Ich muss mit einer der Problemumgehungen zu tun haben. Ich bin immer noch neugierig, warum - ich implizite die Abgrenzung durch Newline. wilhelmtell vor 14 Jahren 0
Gib dir Zeit, jemand anderes könnte eine echte Antwort für dich haben. ich dachte, vielleicht brauchst du die erweiterung, nicht das stdin. quack quixote vor 14 Jahren 0
0
Ryan Thompson

Warum nicht gerade find .h d e.h -name '*.h'?

siehe seinen Kommentar zu meiner Antwort; Er benötigt die Argumentliste von stdin. (Gute Vereinfachung meiner Antwort, zumindest im Beispiel "find" + "echo"). quack quixote vor 14 Jahren 0
Ok, wenn Sie die Liste von stdin benötigen, müssen Sie einen der folgenden Schritte ausführen: 1. Verwenden Sie keine Leerzeichen in Verzeichnisnamen und leiten Sie dann die Elemente durch `sed -e 's / \ s + / \ n / g "; 2. Finden Sie eine Möglichkeit, die eingehenden Verzeichnisnamen durch Zeilenumbrüche oder Nullen zu trennen, und verwenden Sie dann entweder `xargs --null find ...` oder `, während Sie x lesen. tun ... ; fertig ". Ryan Thompson vor 14 Jahren 0
0
user23307

hast du die Option -d für xargs ausprobiert?

justin@eee:~$ echo .h d e.h |xargs -d ' ' -n1 -IA echo foo A foo a.h foo b.h foo c.h foo d foo e.h 

oder noch einfacher,

justin@eee:~$ for x in $(echo .h d e.h);do echo foo $x;done foo a.h foo b.h foo c.h foo d foo e.h 
"-I" impliziert das Ignorieren von "-d". Außerdem verwendet '-d' genau einen Buchstaben als Argument. Sie können kein beliebiges Leerzeichen als Trennzeichen verwenden. Das heißt, in Bezug auf Regex ist es / /, aber Sie können nicht / \ s / oder sogar / \ s + / machen. wilhelmtell vor 14 Jahren 0
funktioniert gut für mich, siehe mein Kommentar. Wenn dies immer noch nicht das ist, was Sie wollen, müssen Sie ein besseres Beispiel geben, das zeigt, was Sie wirklich tun wollen. user23307 vor 14 Jahren 0
0
Ole Tange

Verwenden Sie GNU Parallel:

parallel -q find {} -name '*.h' ::: .h d e.h 

Sehen Sie sich das Intro-Video an, um mehr zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ