GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Suchen Sie nach Textdateien, in denen zwei verschiedene Wörter vorhanden sind (beliebige Reihenfolge, beliebige Zeile)?

Ich suche nach einer Möglichkeit, Dateien zu durchsuchen, in denen zwei Wortinstanzen in derselben Datei vorhanden sind. Bis zu diesem Punkt habe ich Folgendes verwendet, um meine Suchen durchzuführen:

find . -exec grep -l "FIND ME" {} ;

Das Problem, auf das ich stoße, ist, dass das Suchergebnis die Datei nicht liefert, wenn nicht genau ein Leerzeichen zwischen „FIND“ und „ME“ vorhanden ist. Wie passe ich die frühere Suchzeichenfolge an, bei der beide Wörter „FIND“ und „ME“ in einer Datei vorhanden sind, im Gegensatz zu „FIND ME“?

Ich verwende AIX.

Akzeptierte Antwort:

Mit GNU-Tools:

find . -type f  -exec grep -lZ FIND {} + | xargs -r0 grep -l ME

Sie können standardmäßig Folgendes tun:

find . -type f -exec grep -q FIND {} ; -exec grep -l ME {} ;

Aber das würde bis zu zwei grep dauern s pro Datei. Um zu vermeiden, dass so viele grep ausgeführt werden s und immer noch portabel sein, während immer noch alle Zeichen in Dateinamen erlaubt sind, könnten Sie Folgendes tun:

convert_to_xargs() {
  sed "s/[[:blank:]"']/\\&/g" | awk '
    {
      if (NR > 1) {
        printf "%s", line
        if (!index($0, "//")) printf "\"
        print ""
      }
      line = $0
    }'
    END { print line }'
}

export LC_ALL=C
find .//. -type f |
  convert_to_xargs |
  xargs grep -l FIND |
  convert_to_xargs |
  xargs grep -l ME

Die Idee war, die Ausgabe von find umzuwandeln in ein für xargs geeignetes Format (das ein Leerzeichen erwartet (SPC/TAB/NL im C Gebietsschema, YMMV in anderen Gebietsschemas) getrennte Liste von Wörtern, in denen einfache, doppelte Anführungszeichen und umgekehrte Schrägstriche Leerzeichen und einander maskieren können).

Im Allgemeinen können Sie die Ausgabe von find -print nicht nachbearbeiten , weil es die Dateinamen mit einem Zeilenumbruchzeichen trennt und die Zeilenumbruchzeichen, die in Dateinamen vorkommen, nicht maskiert. Zum Beispiel, wenn wir sehen:

./a
./b

Wir haben keine Möglichkeit herauszufinden, ob es sich um eine Datei namens b handelt in einem Verzeichnis namens a<NL>. oder wenn es die beiden Dateien a sind und b im aktuellen Verzeichnis.

Durch die Verwendung von .//. , weil // kann nicht anders in einem Dateipfad als Ausgabe von find erscheinen (weil es kein Verzeichnis mit leerem Namen und / gibt in einem Dateinamen nicht erlaubt ist), wissen wir das, wenn wir eine Zeile sehen, die // enthält , dann ist das die erste Zeile eines neuen Dateinamens. Also können wir dieses awk verwenden Befehl, um alle Zeilenumbruchzeichen zu maskieren, außer denen, die diesen Zeilen vorangehen.

Nehmen wir das obige Beispiel, find würde im ersten Fall (eine Datei) ausgeben:

.//a
./b

Welches awk entkommt zu:

.//a
./b

Damit xargs sieht darin ein Argument. Und im zweiten Fall (zwei Dateien):

.//a
.//b

Welcher awk würde so bleiben wie es ist, also xargs sieht zwei Argumente.

Verwandte:Tmux-Mausmodus erlaubt es nicht, Text mit der Maus auszuwählen?

Sie benötigen den LC_ALL=C also sed , awk (und einige Implementierungen von xargs ) funktionieren für beliebige Folgen von Bytes (auch wenn diese keine gültigen Zeichen in der Ländereinstellung des Benutzers bilden), um das Leerzeichen zu vereinfachen Definition auf nur SPC und TAB und um Probleme mit unterschiedlichen Interpretationen von Zeichen zu vermeiden, deren Codierung die Codierung des Backslash durch die verschiedenen Dienstprogramme enthält.


Linux
  1. Zwei Spalten verschiedener Dateien vergleichen und bei Übereinstimmung drucken?

  2. Wert zwischen zwei Suchmustern in derselben Zeile extrahieren?

  3. Erstellen Sie Dateien mithilfe der Befehlszeile in Linux

  4. Wie suchen Sie mit grep unter Linux nach Dateien, die DOS-Zeilenenden (CRLF) enthalten?

  5. So suchen Sie nach Dateien mit Regex im Linux-Shell-Skript

Newsboat – Ein Befehlszeilen-RSS/Atom-Feed-Reader für Textkonsolen

So fügen Sie Textdateien unter Linux Zeilennummern hinzu

So suchen Sie nach Dateien über die Linux-Befehlszeile

So finden Sie Dateien, die eine bestimmte Textzeichenfolge in Linux enthalten

Linux:Dateierweiterungen für mehrere Dateien entfernen

Wie kann ich nach Dateien suchen und sie in einer Zip-Datei komprimieren?