Regulärer Ausdruck zum Suchen von Doppelzeichen in Bash

10

Ich suche nach einem regulären Ausdruck, der alle Vorkommen von Doppelzeichen in einem Text, einer Auflistung usw. in der Befehlszeile (Bash) findet.

Haupt Frage : Gibt es eine einfache Art und Weise zu suchen Sequenzen wie aa, ll, tttttusw. , wo man definiert ein regulärer Ausdruck , dass sieht für n Vorkommen des gleichen Zeichens mit? Was ich suche, ist dies auf einer sehr sehr grundlegenden Ebene zu erreichen. In der Kommandozeile. In einer Linux-Shell.

Nach einigen Recherchen kam ich zu den folgenden Antworten - und den daraus resultierenden Fragen, daher gaben sie mir nur einen Hinweis, wo die Lösung liegen könnte. Aber:

a) (e) grep und das Backslash-Problem

  • grep 'a\{2\}' schaut nach aa
  • egrep'a{2}' schaut nach aa

Frage: Ist die Notwendigkeit, Spiel zu setzen, wirklich an den von mir verwendeten Befehl gebunden? Wenn ja, kann mir jemand einen Hinweis geben, was bei der Verwendung von (e) grep hier noch zu beachten ist?

b) Ich habe diese Antwort hier für meine Frage gefunden, obwohl es nicht genau das ist, wonach ich gesucht habe:

grep -E '(.)\1' filenamesucht nach Einträgen mit demselben Zeichen, die mehrmals vorkommen, fragt aber nicht, wie oft . Dies kommt dem nahe, wonach ich suche, aber ich möchte immer noch eine Reihe von Wiederholungen festlegen.

Ich sollte das wahrscheinlich in zwei oder mehr Fragen aufteilen, aber dann möchte ich diese großartige Seite hier nicht überfluten.

PS: Noch eine Frage, die möglicherweise aus Thema , aber: ist es in, inside, atoder on the shell. Und ist on the command linerichtig?

erch
quelle

Antworten:

8

Das sind wirklich zwei Fragen, die hätten aufgeteilt werden müssen. Da die Antworten jedoch relativ einfach sind, werde ich sie hier einfügen. Diese Antworten sind grepspeziell für GNU .

a) egrepist das gleiche wie grep -E. Beide geben an, dass "Erweiterte reguläre Ausdrücke" anstelle der grepstandardmäßigen regulären Ausdrücke verwendet werden sollten. greperfordert die Backslashes für einfache reguläre Ausdrücke.

Von der manSeite:

Grundlegende oder erweiterte reguläre Ausdrücke

In regulären Grundausdrücken die Metazeichen ? , + , { , | , ( und ) verlieren ihre besondere Bedeutung; Verwenden Sie stattdessen die Backslashed-Versionen \? , \ + , \ { , \ | , \ ( und \) .

manWeitere Informationen zu historischen Konventionen und Portabilität finden Sie auf der Seite.

b) Verwenden Sie egrep '(.)\1{N}'und ersetzen Sie Ndurch die Anzahl der Zeichen, die Sie ersetzen möchten, minus eins (da der Punkt mit dem ersten übereinstimmt). Wenn Sie also einem viermal wiederholten Zeichen entsprechen möchten, verwenden Sie egrep '(.)\1{3}'.

depquid
quelle
Beim Lesen der Manpage muss ich den Teil, auf den Sie hingewiesen haben, wirklich missverstanden oder falsch interpretiert haben. Als ich einige Tutorials mit regulären Ausdrücken durchgearbeitet habe, waren keine Hinweise auf ein solches Verhalten zu erwarten. Ich dachte, dass regulärer Ausdruck etwas auf einer so grundlegenden Ebene bedeutet, dass die meisten Anwendungen mit denselben Symbolen arbeiten. Wieder wurde mir das Gegenteil bewiesen. Danke für Ihre Hilfe! Das hat mir wirklich geholfen.
Erch
Es ist auch ziemlich verwirrend zu lesen, " immer den umgekehrten Schrägstrich zu verwenden, um die spezielle Bedeutung von Zeichen wie., + Usw. zu übernehmen " und dann herauszufinden, dass anscheinend das Gegenteil die Regel mit dem grundlegendsten Befehl ist.
Erch
@ cellar.dweller Es ist verwirrend! Viele der Überlegungen sind historisch. Ich bin mit der erweiterten Form besser vertraut, daher mache ich es mir zur Gewohnheit, immer nur zu verwenden, egrepwenn ich reguläre Ausdrücke benötige (im Gegensatz zu einfachem String-Matching), damit ich mir keine Gedanken über die Unterschiede zwischen grepden beiden machen muss Arten von regulären Ausdrücken.
depquid
4
Beachten Sie, dass Standard-EREs keine Rückverweise unterstützen, während Standard-BREs dies tun. Ist grep '\(.\)\1\{3\}'also Standard, grep -E '(.)\1{3}'nicht.
Stéphane Chazelas
7

Dies würde nach zwei oder mehr Vorkommen desselben Charakters suchen:

grep -E '(.)\1+' file

Wenn Ihr awk die Option -o hat, wird dies jedes Match in eine neue Zeile drucken.

grep -Eo '(.)\1+' file

So finden Sie Übereinstimmungen mit genau 3 Übereinstimmungen:

grep -E '(.)\1{2}' file

Oder 3 oder mehr:

grep -E '(.)\1{2,}' file

etc..


bearbeiten

Eigentlich geht es bei @stephane_chazelas um Rückverweise und -E. Das hatte ich vergessen. Ich habe es in BSD grep und GNU grep versucht und es funktioniert dort, aber es ist nicht in einigen anderen greps. Sie müssten eine der folgenden Versionen verwenden.

Regelmäßige grep-Versionen:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

Die -oOption ist auch nicht Standard-Grep BTW (wahrscheinlich, wenn Ihr Grep -o versteht, kann er auch die Rückreferenz machen).


Hinweis : grep -E '(.)\1{2,}'Datei und grep '\(.\)\1\{2\}'Datei sind wie angegeben falsch und sollten ignoriert werden.

Scrutinizer
quelle
Vielen Dank bis jetzt. Aber: Habe ich Recht zu sagen, dass ohne die -EOption grepnicht viel tun würde? Dies würde ziemlich viel erklären, zum Beispiel, warum ich so viel Zeit damit verschwendet habe, zu suchen, wo ich falsch lag!
Erch
Ohne die Option -E können Sie in diesem Fall dasselbe tun, aber Sie müssten mehr entkommen und es gibt keinen +Operator. Ich werde auch Beispiele veröffentlichen.
Scrutinizer
Eine kleine Korrektur: grep -E '(.)\1{2}'nicht genau "Übereinstimmungen mit genau 3 Übereinstimmungen finden". Während es wird passen genau drei identische Zeichen, können sie in einem längeren wiederholten Zeichenfolge eingebettet werden; z. B. wird es in der Zeichenfolge mit 5 Symbolen übereinstimmen AAAAA. (Und wenn es 6 oder mehr aufeinanderfolgende Symbole gibt, wird es mehr als einmal übereinstimmen).
Alexis
Ja, Sie haben absolut Recht, das funktioniert nicht wie beabsichtigt, in der Tat ist es nicht so möglich ..
Scrutinizer
3

Zunächst einmal vielen Dank für Ihre unterstützenden Kommentare und Vorschläge. Wie sich herausstellte, war ich der Antwort schon ziemlich nahe.

Das Hauptproblem war über:

Gibt es eine einfache Möglichkeit, nach n Vorkommen desselben Charakters zu suchen , z aa.tttttt

Kurze Antwort :

Die folgenden [Variationen von] Befehlen werden amindestens einmal und unendlich oft wiederholt

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

oder mit regulären GNU-Ausdrücken grep a\+


Die Anzahl der Wiederholungen sind in geschweiften Klammern, durch das Muster festgelegt {min,max}{n}Wiederholung genau nmal, {n,}wiederholen Sie mindestens nmal und {n,m}wiederholen Sie mindestens naber höchstens mmal.

Infolgedessen wurde das sekundäre Problem aufgeworfen :

Ist die Notwendigkeit, Spiel zu setzen, an den von mir verwendeten Befehl gebunden?

Kurze Antwort : Ja, die Verwendung von Backslashes hängt davon ab, ob man grepoder verwendetegrep

  • grep: Backslash aktiviert Metazeichen [verwendet grundlegende reguläre Ausdrücke]
  • egrepBackslash de -activates Metazeichen [Anwendungen Reguläre Ausdrücke Erweiterte]

Da dies die kurze Antwort ist, möchte ich denjenigen, die auf vergleichbare Probleme gestoßen sind, eine grundlegende Zusammenfassung dessen hinzufügen, was man anscheinend wissen muss, mit grepund arbeitet egrep.




Grundlegende, erweiterte und reguläre GNU-Ausdrücke

Grundlegende reguläre Ausdrücke

Verwendet in grep, edund sedBefehl

Grundlegende Funktionen für reguläre Ausdrücke sind:

  • Die meisten Metazeichen, z ? [ . \ ). B. usw., werden durch einen Backslash aktiviert. Wenn es keinen Backslash gibt, werden sie als (Teil des) Suchbegriffs verwendet.
  • ^ $ \<und \>werden ohne Backslash unterstützt
  • Keine Kurzschrift - Zeichen [ \b, \setc.]

GNU Basic Regular Expressions ergänzen diese

  • \?Wiederholen Sie das Zeichen null oder einmal ( c\?entspricht cund cc) und ist eine Alternative für\{0,1\}
  • \+wiederhole ein Zeichen mindestens einmal ( c\+Spiele cc, ccccccccetc.) und ist eine Alternative für\{1,\}

  • \|wird unterstützt (zB grep a\|bwird nach aoder gesuchtb

grep -E Aktiviert den Befehl zur Verwendung des gesamten Satzes der erweiterten regulären Ausdrücke:


Erweiterte reguläre Ausdrücke [ERE]

Verwendet in egrep, awkund emacsist die Basis - Set plus einige ziemlich Funktionen.

  • Metazeichen werden durch einen Backslash deaktiviert
  • Keine Rückverweise
  • sonst: viele der magischen regulären Ausdrücke können normalerweise für einen tun

GNU Erweitern Sie reguläre Ausdrücke

fügt die folgenden Funktionen hinzu

Die beiden Links leiten einen zu regulär-expressions.info, was mir zusätzlich zu der großartigen Unterstützung, die ich hier habe, sehr geholfen hat.

erch
quelle