it-swarm.com.de

So leiten Sie eine Liste der vom Befehl find zurückgegebenen Dateien an cat weiter, um alle Dateien anzuzeigen

Ich mache ein find und bekomme dann eine Liste von Dateien. Wie leite ich es an ein anderes Dienstprogramm wie cat weiter (damit cat den Inhalt all dieser Dateien anzeigt) und muss im Grunde etwas aus diesen Dateien grep.

189
Devang Kamdar
  1. Weiterleiten an einen anderen Prozess (obwohl dies NICHT zu dem führt, was Sie zu tun versucht haben):

    command1 | command2
    

    Dadurch wird die Ausgabe von Befehl1 als Eingabe von Befehl2 gesendet

  2. -exec Auf einem find (dies wird tun, was Sie wollen - ist aber spezifisch für find)

    find . -name '*.foo' -exec cat {} \;
    

    (Alles zwischen find und -exec Sind die Suchprädikate, die Sie bereits verwendet haben. {} Ersetzt die Datei, die Sie im Befehl gefunden haben (cat {}) case); mit \; wird der Befehl -exec beendet.)

  3. die Ausgabe eines Prozesses als Befehlszeilenargumente an einen anderen Prozess senden

    command2 `command1`
    

    zum Beispiel:

    cat `find . -name '*.foo' -print`
    

    (Beachten Sie, dass dies BACK-QUOTES und keine regulären Anführungszeichen sind (unter der Tilde ~ auf meiner Tastatur).) Dadurch wird die Ausgabe von command1 Als Befehlszeilenargument an command2 Gesendet. Beachten Sie, dass Dateinamen mit Leerzeichen (Zeilenumbrüche usw.) in separate Argumente unterteilt werden.

306
kenj0418

Moderne Version

POSIX 2008 fügte find den + - Marker hinzu, was bedeutet, dass jetzt automatisch so viele Dateien wie möglich in einer einzigen Befehlsausführung gruppiert werden, ähnlich wie bei xargs hat jedoch eine Reihe von Vorteilen:

  1. Sie müssen sich keine Gedanken über ungerade Zeichen in den Dateinamen machen.
  2. Sie müssen sich keine Sorgen machen, dass der Befehl mit einem Dateinamen von Null aufgerufen wird.

Das Problem mit dem Dateinamen ist bei xargs ohne die Option -0 Aufgetreten, und das Problem mit der Option -0 Ist das Problem, dass keine Dateinamen angegeben werden. Aber GNU xargs hat die Option -r oder --no-run-if-empty, um dies zu verhindern. Außerdem reduziert diese Notation die Anzahl der Prozesse, nicht, dass Sie wahrscheinlich den Leistungsunterschied messen würden. Daher könnten Sie sinnvollerweise schreiben:

find . -exec grep something {} +

Klassische Version

find . -print | xargs grep something

Wenn Sie unter Linux arbeiten oder die Befehle GNU find und xargs verwenden, verwenden Sie -print0 Mit find und -0 Mit xargs für Dateinamen mit Leerzeichen und anderen Sonderzeichen.

find . -print0 | xargs -0 grep something

Die Ergebnisse von grep optimieren

Wenn Sie die Dateinamen (nur den Text) nicht möchten, fügen Sie grep eine entsprechende Option hinzu (normalerweise -h, Um 'Überschriften' zu unterdrücken). Um absolut zu gewährleisten, dass der Dateiname von grep gedruckt wird (auch wenn nur eine Datei gefunden wird oder der letzte Aufruf von grep nur einen Dateinamen hat), fügen Sie /dev/null in die xargs Befehlszeile, so dass es immer mindestens zwei Dateinamen gibt.

80

Es gibt einige Möglichkeiten, die Liste der vom Befehl find zurückgegebenen Dateien an den Befehl cat zu übergeben, obwohl technisch nicht alle Piping verwenden und keiner direkt an cat weiterleitet. .

  1. Am einfachsten ist die Verwendung von Backticks (`):

    cat `find [whatever]`
    

    Dies nimmt die Ausgabe von find und platziert sie effektiv in der Befehlszeile von cat. Dies funktioniert nicht gut, wenn find zu viele Ausgaben enthält (mehr als in eine Befehlszeile passen) oder wenn die Ausgabe Sonderzeichen enthält (z. B. Leerzeichen).

  2. In einigen Shells, einschließlich bash, kann anstelle von Backticks $() verwendet werden:

    cat $(find [whatever])
    

    Dies ist weniger portabel, aber schachtelbar. Abgesehen davon hat es so ziemlich die gleichen Vorbehalte wie Backticks.

  3. Da das Ausführen anderer Befehle für das, was gefunden wurde, eine häufige Verwendung für find ist, verfügt find über eine -exec - Aktion, die einen Befehl für jede gefundene Datei ausführt:

    find [whatever] -exec cat {} \;
    

    Der {} Ist ein Platzhalter für den Dateinamen, und der \; Markiert das Ende des Befehls. (Nach -exec Können andere Aktionen ausgeführt werden.)

    Dadurch wird cat einmal für jede einzelne Datei ausgeführt, anstatt eine einzelne Instanz von cat auszuführen, wobei mehrere Dateinamen übergeben werden. Dies kann ineffizient sein und möglicherweise nicht das gewünschte Verhalten für einige Befehle aufweisen (obwohl dies in Ordnung ist) für cat). Die Syntax ist auch umständlich zu tippen - Sie müssen das Semikolon umgehen, da das Semikolon für die Shell etwas Besonderes ist!

  4. Bei einigen Versionen von find (insbesondere der GNU) -Version) können Sie ; Durch + Ersetzen, um -exec Zu verwenden. ' s Append-Modus, um weniger Instanzen von cat auszuführen:

    find [whatever] -exec cat {} +
    

    Dadurch werden jedem Aufruf von cat mehrere Dateinamen übergeben, was effizienter sein kann.

    Beachten Sie, dass dies nicht garantiert ist, um einen einzelnen Aufruf zu verwenden. Wenn die Befehlszeile zu lang wäre, werden die Argumente auf mehrere Aufrufe von cat verteilt. Für cat ist dies wahrscheinlich keine große Sache, aber für einige andere Befehle kann dies das Verhalten auf unerwünschte Weise ändern. Auf Linux-Systemen ist die Begrenzung der Befehlszeilenlänge ziemlich groß, so dass die Aufteilung in mehrere Aufrufe im Vergleich zu einigen anderen Betriebssystemen sehr selten ist.

  5. Der klassische/portable Ansatz ist die Verwendung von xargs:

    find [whatever] | xargs cat
    

    xargs führt den angegebenen Befehl aus (in diesem Fall cat) und fügt Argumente hinzu, die auf dem basieren, was von stdin gelesen wird. Genau wie bei -exec Mit + Wird hierdurch die Befehlszeile bei Bedarf getrennt. Das heißt, wenn find zu viel ausgibt, wird cat mehrmals ausgeführt. Wie bereits im Abschnitt über -exec Erwähnt, gibt es einige Befehle, bei denen diese Aufteilung zu einem anderen Verhalten führen kann. Beachten Sie, dass die Verwendung von xargs Probleme mit Leerzeichen in Dateinamen hat, da xargs nur Leerzeichen als Trennzeichen verwendet.

  6. Die robusteste, portabelste und effizienteste Methode verwendet auch xargs:

    find [whatever] -print0 | xargs -0 cat
    

    Das Flag -print0 Weist find an, \0 (Nullzeichen) Trennzeichen zwischen Dateinamen zu verwenden, und das Flag -0 Weist xargs an, diese zu erwarten \0 Trennzeichen. Dies ist ziemlich identisch mit dem Ansatz -exec ... +, Ist jedoch portabler (aber leider ausführlicher).

34

Um dies zu erreichen (mit bash) würde ich wie folgt vorgehen:

cat $(find . -name '*.foo')

Dies wird als "Befehlsersetzung" bezeichnet und entfernt standardmäßig den Zeilenvorschub, was sehr praktisch ist!

mehr Infos hier

9
Stphane

Klingt für mich wie ein Job für ein Shell-Skript:

for file in 'find -name *.xml'
do
   grep 'hello' file
done

oder etwas ähnliches

6
Gandalf

So finden Sie Dateinamen mit Inhalten, an denen ich interessiert bin, nur eine einzige Bash-Zeile, die auch mit Leerzeichen in Dateinamen umgehen kann:

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
4
Greg

Ich benutze so etwas:

find . -name <filename> -print0 | xargs -0 cat | grep <Word2search4>

"-print0 "Argument für" find "und" -0 "Argument für" xargs "werden benötigt, um Leerzeichen in Dateipfaden/-namen korrekt zu behandeln.

3
ekinak

Der find-Befehl hat ein -exec-Argument, das Sie für solche Dinge verwenden können. Sie können das grep auch direkt damit ausführen.

Zum Beispiel ( von hier aus andere gute Beispiele auf dieser Seite ):

find . -exec grep "www.athabasca" '{}' \; -print 
2
Chad Birch

In der Bash wäre Folgendes angebracht:

find /dir -type f -print0 | xargs -0i cat {} | grep whatever

Dies findet alle Dateien im Verzeichnis /dir Und leitet die Dateinamen sicher in xargs weiter, wodurch grep sicher ausgeführt wird.

Das Überspringen von xargs ist keine gute Idee, wenn Sie viele tausend Dateien in /dir Haben. cat bricht aufgrund einer zu langen Argumentliste ab. xargs erledigt das für Sie.

Das Argument -print0 Für find passt zum Argument -0 Für xargs, um Dateinamen mit Leerzeichen richtig zu behandeln. Mit dem Argument -i Für xargs können Sie den Dateinamen an der erforderlichen Stelle in die Befehlszeile von cat einfügen. Die Klammern werden durch den Dateinamen ersetzt, der von cat in den Befehl find eingefügt wird.

2
McClain Looney

Hier ist meine Aufnahme für den allgemeinen Gebrauch:

grep YOURSTRING `find .`

Der Dateiname wird gedruckt

2
zakki

Das funktioniert bei mir

find _CACHE_* | while read line; do
    cat "$line" | grep "something"
done
0
Steven Penny

Dadurch werden Name und Inhalt von Dateien nur rekursiv gedruckt.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
0

Verwenden Sie ggrep .

ggrep -H -R -I "mysearchstring" *

um nach einer Datei in Unix zu suchen, die Text enthält, der sich im aktuellen Verzeichnis oder in einem Unterverzeichnis befindet

0
Underverse