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 e
Zeichen 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 df
meinem 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) -o
Option, um eine Liste nicht überlappender Übereinstimmungen in separaten Zeilen zurückzugeben. Diese Zeilen werden dann mit gezählt wc -l
.
Der Aufruf von grep
uses -F
bewirkt, 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 -F
es weg, wenn Sie das Muster als regulären Ausdruck verwenden möchten.
Die -e
Option wird verwendet, um anzugeben, grep
dass $1
es sich um das Muster handelt. Wenn -e
nicht verwendet wird, --version
wird 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.