Textdatei mit einem bestimmten Text suchen und dabei neue Zeilen und Leerzeichen ignorieren?

Textdatei mit einem bestimmten Text suchen und dabei neue Zeilen und Leerzeichen ignorieren?

Ich habe eine Zeichenfolge wie: "thisissometext". Ich möchte alle Textdateien in einem bestimmten Verzeichnis (rekursiv) finden, die diese Zeichenfolge oder Variationen davon mit Leerzeichen und/oder Zeilenumbrüchen in der Mitte enthalten. Beispielsweise sollte eine Textdatei, die , "this is sometext"oder enthält "this\n issometext", "this\n isso metext" in der Suche angezeigt werden. Wie kann ich das tun?

Antwort1

Bei den neueren Versionen von GNU grep(die diese -zOption haben) können Sie diesen Einzeiler verwenden:

find . -type f -exec grep -lz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' {} +

Beachten Sie, dass Leerzeichen nur zwischen den Wörtern stehen dürfen.

Wenn Sie einfach alle Dateien rekursiv ab dem aktuellen Verzeichnis durchsuchen möchten, brauchen Sie nicht find, Sie können einfach grep -r(rekursiv) verwenden. findkann verwendet werden, um selektiv nach Dateien zu suchen, z. B. um Dateien auszuwählen, deren Verzeichnis ausgeschlossen werden soll. Also einfach:

grep -rlz 'this[[:space:]]*is[[:space:]]*some[[:space:]]*text' .
  • Der Haupttrick besteht hier darin -z, dass jede Zeile des Eingabestroms, die mit ASCII NUL endet, statt als neue Zeile behandelt wird, sodass wir Zeilenumbrüche mithilfe der üblichen Methoden abgleichen können.

  • [[:space:]]Das Zeichenklassenmuster gibt alle Leerzeichen an, einschließlich Leerzeichen, Tabulatoren, CR, LF usw. Wir können es also verwenden, um alle Leerzeichen abzugleichen, die zwischen den Wörtern stehen können.

  • grep -ldruckt nur die Dateinamen, die eines der gewünschten Muster aufweisen. Wenn Sie auch die Übereinstimmungen drucken möchten, verwenden Sie -Hanstelle von -l.

Wenn die Leerzeichen andererseits an beliebigen Stellen und nicht zwischen den Wörtern stehen können, würde dies sein gutes Aussehen verlieren:

grep -rlz
't[[:space:]]*h[[:space:]]*i[[:space:]]*s[[:space:]]*i[[:space:]]*\
s[[:space:]]*s[[:space:]]*o[[:space:]]*m[[:space:]]*e[[:space:]]*\
t[[:space:]]*e[[:space:]]*x[[:space:]]*t' .

Mit -Pder Option (PCRE) können Sie das [[:space:]]durch Folgendes ersetzen \s(das würde viel schöner aussehen):

grep -rlzP 't\s*h\s*i\s*s\s*i\s*s\s*s\s*o\s*m\s*e\s*\
t\s*e\s*x\s*t' .

sedDie beste Option wäre, den Vorschlag von @steeldriver zu verwenden, um das Muster für uns zu generieren:

grep -rlzP "$(sed 's/./\\s*&/2g' <<< "thisissometext")" .

Antwort2

Sie können alle Leerzeichen löschen und sie greppen:

tr -d '[[:space:]]' < foo | grep thisissometext

Erweiterung:

find . -type f -exec bash -c 'for i; do tr -d "[[:space:]]" < "$i" | grep -q thisissometext && printf "%s\n" "$i"; done' _ {} +

Der basherweiterte Befehl:

for i
do
    tr -d "[[:space:]]" < "$i" | 
      grep -q thisissometext && 
      printf "%s\n" "$i"
done

Dies durchläuft eine Schleife über alle Argumente und verwendet den obigen Test.

Antwort3

Der folgende Code durchsucht ein Verzeichnis rekursiv nach Dateien und entfernt alle Vorkommen von " "und "\n". Wenn die Zeichenfolge im verbleibenden Text vorhanden ist, gibt es eine Übereinstimmung. Dies bedeutet, dass die Leerzeichen/Zeilenumbrüche aufbeliebigPosition in der Zeichenfolge innerhalb Ihrer Datei(en).

Was es macht

Wenn übereinstimmende Dateien gefunden werden, werden diese zusammen mit ihren Pfaden im Terminal ausgegeben, etwa:

/home/jacob/Bureaublad/testmap/test2.txt
/home/jacob/Bureaublad/testmap/Naamloze map 2/test1.txt

Das Try/Except-Feature habe ich eingebaut, um zu verhindern, dass das Skript abbricht, wenn es auf eine nicht lesbare Datei stößt.

Das Drehbuch

#!/usr/bin/env python3
import os
import sys

s = sys.argv[2]
for root, dirs, files in os.walk(sys.argv[1]):
    for file in files:
        file = root+"/"+file
        try:
            if s in open(file).read().replace(" ", "").replace("\n",""):
                print(file)
        except:
            pass

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unterfind_string.py
  2. Führen Sie es mit dem Verzeichnis und der Zeichenfolge als Argumente aus:

    python3 /path/to/find_string.py <directory> <string_to_find>
    

    Wenn entweder die Zeichenfolge oder das Verzeichnis Leerzeichen enthält, verwenden Sie Anführungszeichen:

    python3 /path/to/find_string.py '<directory>' '<string_to_find>'
    

Notiz

Das Skript findet Dateien mit der Zeichenfolge, die entweder Leerzeichen oder Zeilenumbrüche enthält. Es kann mit anderen Zeichen/Zeichenfolgen (z. B. Tabulatoren) in der Zeile erweitert werden:

if s in open(file).read().replace(" ", "").replace("\n",""):

Antwort4

Sie können grep -i --recursive 'word1\|word2' *und awk '/word1/,/word2/'können verwendet werden, um mit der Newline umzugehen

Bildbeschreibung hier eingeben

verwandte Informationen