Ich mache eine find
und bekomme dann eine Liste von Dateien. Wie leite ich es an ein anderes Dienstprogramm wie cat
(damit cat den Inhalt all dieser Dateien anzeigt) und brauche im Grunde grep
etwas aus diesen Dateien.
Weiterleitung an einen anderen Prozess (obwohl dies NICHT das erreicht, was Sie gesagt haben, dass Sie versuchen zu tun):
command1 | command2
Dadurch wird die Ausgabe von Befehl1 als Eingabe von Befehl2 gesendet
-exec
auf a find
(dies wird tun, was Sie tun möchten - 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 bestimmte Datei, die Sie im Befehl gefunden haben ( cat {}
in diesem Fall). Dies \;
ist das Beenden des -exec
Befehls.)
Senden Sie die Ausgabe eines Prozesses als Befehlszeilenargumente an einen anderen Prozess
command2 `command1`
beispielsweise:
cat `find . -name '*.foo' -print`
(Beachten Sie, dass dies BACK-QUOTES sind, keine regulären Anführungszeichen (unter der Tilde ~ auf meiner Tastatur).) Dadurch wird die Ausgabe von command1
in command2
als Befehlszeilenargumente gesendet. Beachten Sie jedoch, dass Dateinamen mit Leerzeichen (Zeilenumbrüche usw.) in separate Argumente unterteilt werden.
find -name '*.foo' -print
hat großartig für mich gearbeitet ... Dankefind
Folgendes schreiben können :find . -name '*.foo' -exec cat {} +
, wobei+
angegeben wird, dassfind
so viele Dateinamen wie möglich in einem einzigen Befehlsaufruf zusammengefasst werden sollen. Dies ist sehr nützlich (es behandelt Leerzeichen usw. in Dateinamen, ohne auf-print0
und zurückzugreifenxargs -0
).find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
Moderne Version
POSIX 2008 hat den
+
Marker hinzugefügt ,find
was bedeutet, dass jetzt automatisch so viele Dateien wie möglich in einer einzigen Befehlsausführung zusammengefasst werden, ähnlich wie dies derxargs
Fall ist, jedoch mit einer Reihe von Vorteilen:Das Problem mit
xargs
dem Dateinamen ist ein Problem ohne die-0
Option, und das Problem "Auch ohne Dateinamen ausführen" ist ein Problem mit oder ohne die-0
Option - aber GNUxargs
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. Daher könnte man vernünftigerweise schreiben:Klassische Version
Wenn Sie unter Linux arbeiten oder über GNU
find
undxargs
Befehle verfügen , verwenden Sie-print0
mitfind
und-0
mitxargs
Dateinamen, die Leerzeichen und andere ungerade Zeichen enthalten.Optimieren der Ergebnisse von
grep
Wenn Sie die Dateinamen (nur den Text) nicht möchten, fügen Sie eine entsprechende Option hinzu
grep
(normalerweise-h
zum Unterdrücken von 'Überschriften'). Um absolut zu gewährleisten, dass der Dateiname von gedruckt wirdgrep
(auch wenn nur eine Datei gefunden wird oder der letzte Aufruf vongrep
nur 1 Dateinamen enthält), fügen Sie ihn/dev/null
zurxargs
Befehlszeile hinzu, sodass immer mindestens zwei Dateinamen vorhanden sind.quelle
xargs grep something
.find
wird an den Standardeingang von weitergeleitetxargs
. Dasxargs
Programm liest seine Standardeingabe, teilt die Eingabe im Leerraum (Leerzeichen, Zeilenumbrüche, Tabulatoren usw.) auf, hängt eine Reihe von Wörtern an den Befehl angrep something
und führt die Befehlszeile aus.xargs
Lesen Sie dann die Eingabe weiter und führen Sie die Befehle aus, bis die Eingabe aufgebraucht ist.xargs
führt dengrep
Befehl so oft aus, wie es für die Eingabe erforderlich ist (find
in diesem Beispiel)./dev/null
die Fehlermeldungen zu verlieren.Es gibt einige Möglichkeiten, die Liste der vom
find
Befehl zurückgegebenen Dateien an den Befehl zu übergebencat
, obwohl technisch nicht alle Piping verwenden und keine direkt ancat
.Am einfachsten ist es, backticks (
`
) zu verwenden:Dies nimmt die Ausgabe von
find
und platziert sie effektiv in der Befehlszeile voncat
. Dies funktioniert nicht gut, wennfind
zu viel ausgegeben wird (mehr als in eine Befehlszeile passen kann) oder wenn die Ausgabe Sonderzeichen enthält (wie Leerzeichen).In einigen Shells, einschließlich
bash
, kann man$()
anstelle von Backticks verwenden:Dies ist weniger portabel, aber verschachtelbar. Abgesehen davon hat es so ziemlich die gleichen Einschränkungen wie Backticks.
Da das Ausführen anderer Befehle für das, was gefunden wurde, häufig verwendet
find
wird, verfügt find über eine-exec
Aktion, die einen Befehl für jede gefundene Datei ausführt:Das
{}
ist ein Platzhalter für den Dateinamen und\;
markiert das Ende des Befehls (es ist möglich, dass danach andere Aktionen ausgeführt werden-exec
.)Dies wird
cat
einmal für jede einzelne Datei ausgeführt, anstatt eine einzelne Instanz auszuführen, in dercat
mehrere Dateinamen übergeben werden. Dies kann ineffizient sein und möglicherweise nicht das gewünschte Verhalten für einige Befehle aufweisen (obwohl dies für in Ordnung istcat
). Die Syntax ist auch umständlich einzugeben - Sie müssen das Semikolon umgehen, da das Semikolon für die Shell etwas Besonderes ist!Einige Versionen von
find
(vor allem der GNU - Version) können Sie ersetzen;
mit+
zu verwenden-exec
‚s Zufügen - Modus zu weniger Instanzen ausführencat
:Dadurch werden an jeden Aufruf von mehrere Dateinamen übergeben
cat
, was effizienter sein kann.Beachten Sie jedoch, dass nicht garantiert wird, dass ein einzelner Aufruf verwendet wird. Wenn die Befehlszeile zu lang wäre, werden die Argumente auf mehrere Aufrufe von verteilt
cat
. Fürcat
diese ist wahrscheinlich keine große Sache, aber für einige andere Befehle kann dies das Verhalten in unerwünschter Weise verändern. Auf Linux-Systemen ist die Beschränkung der Befehlszeilenlänge recht groß, sodass die Aufteilung in mehrere Aufrufe im Vergleich zu einigen anderen Betriebssystemen eher selten ist.Der klassische / tragbare Ansatz besteht darin, Folgendes zu verwenden
xargs
:xargs
führt den angegebenen Befehl aus (cat
in diesem Fall) und fügt Argumente hinzu, die auf dem basieren, was von stdin gelesen wird. Genau wie-exec
bei+
wird dadurch die Befehlszeile bei Bedarf unterbrochen. Das heißt, wennfind
zu viel Ausgabe erzeugt wird, wird siecat
mehrmals ausgeführt. Wie bereits in diesem Abschnitt-exec
erwähnt, gibt es einige Befehle, bei denen diese Aufteilung zu einem anderen Verhalten führen kann. Beachten Sie, dass die Verwendung aufxargs
diese Weise Probleme mit Leerzeichen in Dateinamen hat, daxargs
nur Leerzeichen als Trennzeichen verwendet werden.Die robusteste, tragbarste und effizienteste Methode verwendet außerdem
xargs
:Das
-print0
Flag weistfind
an,\0
Trennzeichen (Nullzeichen) zwischen Dateinamen zu verwenden, und das-0
Flag weistxargs
an, diese\0
Trennzeichen zu erwarten . Dies hat ein ziemlich identisches Verhalten wie der-exec
...+
Ansatz, ist jedoch portabler (aber leider ausführlicher).quelle
ls
.$()
auch mit anderen Befehlen alsfind
.Um dies zu erreichen (mit bash), würde ich wie folgt vorgehen:
Dies ist als "Befehlsersetzung" bekannt und entfernt standardmäßig den Zeilenvorschub, was sehr praktisch ist!
Weitere Infos hier
quelle
Klingt für mich nach einem Job für ein Shell-Skript:
oder etwas ähnliches
quelle
Hier ist meine Möglichkeit, Dateinamen zu finden, die Inhalte enthalten, an denen ich interessiert bin, nur eine einzige Bash-Zeile, die auch Leerzeichen in Dateinamen gut verarbeitet:
quelle
Ich benutze so etwas:
"
-print0
" Argumente für "find" und "-0
" Argumente für "xargs" werden benötigt, um Leerzeichen in Dateipfaden / -namen korrekt zu behandeln.quelle
Der Befehl find hat ein Argument -exec, das Sie für solche Dinge verwenden können. Sie können das grep einfach direkt damit ausführen.
Zum Beispiel ( von hier aus andere gute Beispiele auf dieser Seite ):
quelle
Hier ist mein Schuss für den allgemeinen Gebrauch:
Der Dateiname wird gedruckt
quelle
In Bash wäre Folgendes angemessen:
Dadurch werden alle Dateien im
/dir
Verzeichnis gefunden und die Dateinamenxargs
sicher weitergeleitet, wodurch sie sicher fahrengrep
.Das Überspringen
xargs
ist keine gute Idee, wenn Sie viele tausend Dateien haben/dir
.cat
wird aufgrund übermäßiger Länge der Argumentliste unterbrochen.xargs
wird das alles für Sie klären.Das
-print0
zufind
vernetzende Argument mit dem-0
Argument,xargs
Dateinamen mit Leerzeichen richtig zu behandeln. Mit dem-i
Argument toxargs
können Sie den Dateinamen an der erforderlichen Stelle in diecat
Befehlszeile einfügen . Die Klammern werden durch den Dateinamen ersetzt, der in dencat
Befehl von weitergeleitet wirdfind
.quelle
Das funktioniert bei mir
quelle
Verwenden Sie ggrep .
um nach einer Datei unter Unix zu suchen, die Text enthält, der sich im aktuellen Verzeichnis oder in einem Unterverzeichnis befindet
quelle
Dadurch werden der Name und der Inhalt von Dateien nur rekursiv gedruckt.
Bearbeiten (verbesserte Version): Hiermit werden Name und Inhalt von Textdateien (ASCII) nur rekursiv gedruckt.
Noch ein Versuch
quelle
Versuchen Sie, Text in Dateien zu finden? Sie können einfach grep dafür verwenden ...
quelle
Zum Auflisten und Anzeigen des Inhalts aller abc.def-Dateien auf einem Server in den Verzeichnissen / ghi und / jkl
Um die abc.def-Dateien mit kommentierten Einträgen aufzulisten und anzuzeigen, sehen Sie sich diese Einträge in den Verzeichnissen / ghi und / jkl an
quelle