Wie kann ich mit Leerzeichen in Dateinamen umgehen, wenn ich xargs für Suchergebnisse verwende?

28

Eine meiner üblichen Vorgehensweisen besteht darin, alle Dateien eines bestimmten Typs zu prüfen, z. B. alle HTML-Dateien zu finden, in denen das Wort "Rumpus" vorkommt. Um es zu tun, benutze ich

find /path/to -name "*.html" | xargs grep -l "rumpus"

Gelegentlich findwird eine Datei mit einem Leerzeichen im Namen wie zurückgegeben my new file.html. Bei der xargsÜbergabe an greperhalte ich jedoch die folgenden Fehler:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

Ich kann sehen, was hier vor sich geht: Entweder die Pipe oder die xargsbehandelt die Leerzeichen als Begrenzer zwischen Dateien. Für das Leben von mir kann ich jedoch nicht herausfinden, wie ich dieses Verhalten verhindern kann. Kann man das mit find+ machen xargs? Oder muss ich einen ganz anderen Befehl verwenden?

abeger
quelle

Antworten:

29

Verwenden

find ... -print0 | xargs -0 ...

z.B

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

von der Suchmanpage

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
user9517 unterstützt GoFundMonica
quelle
15

Sie müssen keine xargs verwenden , da find Befehle selbst ausführen kann. Dabei müssen Sie sich nicht um die Shell kümmern, die die Zeichen im Namen interpretiert.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

von der Suchmanpage

Befehl -exec {} +
Diese Variante der Aktion -exec führt den angegebenen Befehl für die ausgewählten Dateien aus. Die Befehlszeile wird jedoch erstellt, indem jeder ausgewählte Dateiname am Ende angehängt wird. Die Gesamtzahl der Aufrufe des Befehls ist viel geringer als die Anzahl der übereinstimmenden Dateien. Die Befehlszeile ist in etwa so aufgebaut wie die Befehlszeilen von xargs. Innerhalb des Befehls ist nur eine Instanz von {} zulässig. Der Befehl wird im Startverzeichnis ausgeführt.

Sciurus
quelle
Ich würde dem zustimmen, aber ich bin heute nicht abgereist - ich mache es morgen.
user9517 unterstützt GoFundMonica
1
@Iain - los geht's (da stimme ich übrigens zu).
Eduardo Ivanec
Wenn Sie find verwenden, verpassen Sie immer noch die Funktionen von xargs. Außerdem müssen Sie sich mit albernen Zitierregeln auseinandersetzen. Lesen Sie das Argument -P für xargs, wenn Sie mehr als einen Kern / eine CPU haben.
Slartibartfast
8

Wenn Fund und xarg Versionen auf Ihrem System nicht unterstützt -print0und -0Schalter (zum Beispiel AIX find und xargs) können Sie verwenden:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

Hier kümmert sich sed darum, die Plätze für Xargs zu verlassen.

Jan Ptáčník
quelle
Das hat mir geholfen, weil ich eine lange Liste von Dateinamen hatte, die schwierig zu produzieren war und die ich mehrmals verwendet habe. Ich kann nicht einfach findalle wieder gehen.
Scott M.