Testen von Regex von stdin mit grep | sed | awk

7

Manchmal möchte ich testen, ob meine Regex korrekt ist.

Wie kann ich Reverse regexMatch von stdin machen?

Zum Beispiel kann ich einen String mit dem bereitgestellten regulären Ausdruck abgleichen, wie zum Beispiel:

grep "\(foo\)-bar"
foo
bar
foo-bar
foo-bar #Match found

Was ich tun möchte, ist das Gegenteil, so etwas:

$ grep "This is one string"
\(This\) #Will send "This" to stdout
This?.*  #Will send full match

Ist das irgendwie ohne viel Scripting möglich?

Flüchtling
quelle
Das Entkommen aus den Klammern impliziert die Gruppierung in sed. Andernfalls gruppieren awk und grep "This" nutzlos und sollten stattdessen die gesamte Zeile (in Ihrem Beispiel) ausgeben, nicht nur "This". Können Sie klären, nach welchem ​​Verhalten Sie suchen?
Jeff Schaller

Antworten:

5

Sie können -als "Datei" für die Suche verwenden, wobei die Standardeingabe als "Heuhaufen" verwendet wird, um nach passenden "Nadeln" zu suchen in:

$ grep -oE '[aeiou]+' -
This is a test  < input
i               > output
i               > output
a               > output
e               > output
whaaaat?        < input
aaaa            > output

Verwenden Sie Ctrl- D, um EOFden Stream zu senden und zu beenden.

Ich glaube jedoch nicht, dass Sie dasselbe tun können, um die Standardeingabe für den -fSchalter zu verwenden, der eine Liste von Mustern aus einer Datei liest. Wenn Sie jedoch viele Muster für Text auf einem Korpus haben, können Sie:

grep -f needle-patterns haystack.txt

Dabei needle-patternshandelt es sich um eine Klartextdatei mit einem regulären Ausdruck pro Zeile.

DopeGhoti
quelle
Ja, genau das, was ich brauche :)
Flüchtling
1
@fugitive Aber alles, was es tut, ist die Eingabe von stdin, der Rest ist der gleiche. Es braucht kein Regex-Muster This?.*, wie Sie gefragt haben.
MiniMax
1
Hier kommt die Alternative einer Liste von zu testenden Mustern ins Spiel. Leider können Sie nicht grep -f - haystack, es wird sich beschweren, dass die Datei -nicht existiert.
DopeGhoti
Im Gegenteil: mit GNU grep, Sie können verwenden grep -f - haystack, aber es ist nicht sehr nützlich ohnehin für Zwecke des OP , weil sie warten, bis Sie Strg-D , um die Signaleingabeende drücken, und dann für jede Zeile in „Heuhaufen“ wird es nur entweder drucken oder nicht drucken - es wird nicht mehrmals gedruckt, wenn es mit mehreren Mustern übereinstimmt, und es wird nichts gedruckt, bis Sie alle Ihre Muster eingegeben haben.
Wildcard
2
@fugitive Dies ist vielleicht das, was Sie wollen, aber überhaupt nicht das, was Sie beschrieben haben. Sie haben darum gebeten, interaktiv Muster einzugeben, die mit einer bestimmten Zeichenfolge übereinstimmen. Dabei wird jedoch nach einem Muster in einer interaktiv eingegebenen Zeichenfolge gesucht, wie Sie es bereits hatten. Die Lösung von Wildcard hat Ihre Frage beantwortet!
Philippos
7

Definieren Sie die folgende Funktion in Ihrer Shell (Sie können sie einfach eingeben oder in Ihre Shell einfügen ~/.bashrc):

testregex() {
  [ "$#" -eq 1 ] || return 1
  while IFS= read -r line; do
    printf '%s\n' "$1" | grep -Eoe "$line"
  done
}

Dann können Sie eine Regex wie folgt testen:

$ testregex 'This is a line'
This            <--input
This            <--output
This?.*         <--input
This is a line  <--output
slkdjflksdj     <--input with no output (no match)
s.*             <--input
s is a line     <--output
$               <--I pressed Ctrl-D to end the test
Platzhalter
quelle
3
Dies ist eine großartige Lösung! Ordentlich und einfach. Sie können es auch leicht erweitern, um ein zweites Argument zuzulassen, und, falls vorhanden, dieses Argument an übergeben grep. Auf diese Weise können Sie mit BRE, ERE, PCRE und allem spielen, wofür Sie grepFlaggen haben.
Terdon
Großartig auch.
Flüchtling
Ich möchte Musterpufferung hinzufügen und kann sed | awk | grep-Parameter sein, dann wird es ein sehr nützliches Dienstprogramm für die Musterauswahl sein. Führen Sie es aus testregex -program=sed 'This is a line', geben Sie ihm verschiedene Mustervarianten, rufen Sie das vorherige Muster mit den Pfeiltasten ab und bearbeiten Sie es - ähnlich wie im Bash-Befehlsverlauf. Weil es nicht sehr praktisch ist, jedes Mal ein ganzes Muster neu einzugeben.
MiniMax
Es scheint, dafür muss die gesamte Readline-Bibliothek implementiert werden - für die Musterbearbeitung usw. :)
MiniMax