So machen Sie Grep nicht gierig

So machen Sie Grep nicht gierig

Ich habe eine Datei, die ungefähr so ​​aussieht:

helsoidfiejoih
heye heye hey 
me is hi

Die Datei kann eine beliebige Anzahl von Zeilen oder Zeichen enthalten, es handelt sich also um eine Art Textdatei. Jetzt muss ich grep verwenden, um eine Operation auszuführen, sodass der erste an grep übergebene Parameter der Dateiname und der zweite Parameter das Muster ist. Aber grep führt eine gierige Übereinstimmung durch, sodass es mit der gesamten Zeile übereinstimmt, anstatt mit einer nicht gierigen Übereinstimmung, was ich möchte (nicht gierige Übereinstimmung). Jetzt habe ich Folgendes versucht:

grep -Ec -Po "$2" $1

Es gibt mir widersprüchliche Ausdrücke. Und der Benutzer kann jedes beliebige Muster eingeben, also AKA RE, also ist -E eine notwendige Option. Gibt es eine Möglichkeit, grep nicht gierig zu machen? Mir wurde gesagt, dass die Option -P den grep-Befehl nicht gierig macht, aber nach dem Ausprobieren:

grep -c -Po "$2" $1

Es scheint nicht so, dass der Grep-Ausdruck nicht gierig wird??

Bearbeiten: Die Leute sagten, ich zeige nicht die Muster, mit denen ich arbeite, also um klarzustellen, dass die Muster ein RE sein werden, also zum Beispiel, wenn der Benutzer Eingaben in

./thisfile.sh h file1.txt

Es wird ermittelt, wie oft h in file1.txt vorkommt. Wenn der Benutzer in

./thisfile.sh io file1.txt

Es wird ermittelt, wie oft „io“ in file1.txt vorkommt. Gibt es eine Möglichkeit, dies zu tun?

Antwort1

So zählen Sie, wie oft eine Teilzeichenfolge in einer Datei vorkommt:

#!/bin/sh

grep -F -o -e "$1" | wc -l

Sie würden dieses Skript folgendermaßen verwenden:

$ ./script e <script
       2
$ ./script ' -' <script
       4
$ ./script hey <file1
       3
$ ./script he <file1
       4
$ df | ./script %
       7

Hier zähle ich die Anzahl der eZeichen im Skript selbst und dann, wie oft die Teilzeichenfolge, die aus einem Leerzeichen und einem Bindestrich besteht, im Skript vorkommt. Dann zähle ich einige Teilzeichenfolgen in der in der Frage angegebenen Datei. Das letzte Beispiel zählt die Anzahl der Prozentzeichen in der Ausgabe auf dfmeinem System.

Die Eingabedaten werden über die Standardeingabe gelesen und das einzige Argument des Skripts ist die Teilzeichenfolge, die wir suchen und zählen möchten.

Das Skript besteht aus einer einzelnen grep+ wc-Pipeline. Es verwendet die nicht standardmäßige (aber häufig implementierte) -oOption, um eine Liste nicht überlappender Übereinstimmungen in separaten Zeilen zurückzugeben. Diese Zeilen werden dann mit gezählt wc -l.

Der Aufruf von grepuses -Fbewirkt, dass das Muster als String und nicht als regulärer Ausdruck interpretiert wird. Dadurch ist es möglich, die Anzahl der *Vorkommen von eg in einer Datei zu zählen, ohne escapen zu müssen *(Sie müssten immer nochZitatum *zu verhindern, dass die Shell es als Globbing-Muster verwendet). Lassen Sie -Fes weg, wenn Sie das Muster als regulären Ausdruck verwenden möchten.

Die -eOption wird verwendet, um anzugeben, grepdass $1es sich um das Muster handelt. Wenn -enicht verwendet wird, --versionwird ein Muster wie als Option für interpretiert grep.

Antwort2

Einige Versionen grep(z. B. GNU) erlauben die Angabe von Perl-kompatiblen REs (siehePCRE) sind diese viel flexibler als Standard-POSIX-Regexe.

verwandte Informationen