Ich versuche, einen grep-Befehl zu schreiben, um Zeilen wie die folgenden in einer großen Textdatei zu finden:
<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle">
Das +
Symbol scheint jedoch Probleme mit den folgenden Befehlen zu verursachen:
grep 'data=[a-z,0-9,\"]' file
Viele Treffer
grep 'data=[a-z,0-9,\"]+' file
Keine Treffer
command-line
grep
regex
Martin KS
quelle
quelle
LC_ALL="C" grep ...
stattgrep ...
, so dass [az] immer ASCII-Buchstaben a bis z (dh alle ASCII-Kleinbuchstaben) anstelle von lustigen Alternativen bedeutet (z. B. alle Buchstaben außer "Z", in einige Orte ...)[a-z,0-9,\"]
enthält 2 Vorkommen von ",", was nicht notwendig ist. Sie können den gleichen Effekt mit[a-z,0-9\"]
Antworten:
Wenn Sie
+
"eines oder mehrere der vorhergehenden Atome" bedeuten möchten , müssen Sie eines der folgenden Aktionen ausführen:Verwendung
-E
(Extended Regular Expressions) (oder-P
PCRE):Escape,
+
damit dies speziell in den Standardausdrücken behandelt wird, die standardmäßig verwendet werden ingrep
:quelle
data=
, können Sie einfach ausführengrep -P 'data=".+?"
oder, um nur die Zeichenfolge und sonst nichts zu erhalten :grep -oP '\bdata="\K[^"]+'
.-o
Option. Ich habe meinen vorherigen Kommentar bearbeitet. Und du bist willkommen :)sed -n 's/.*data="\([^"][^"]*\)".*/\1/p' file
, was vollständig POSIX-kompatibel ist . (Undsed -nE 's/.*data="([^"]+)".*/\1/p' file
wird POSIX-konform für die nächste Ausgabe von POSIX sein.)Punkte:
+
ist ein ERE-Token (Extended Regular Expression), das angibt, dass eines oder mehrere der vorhergehenden Token verwendet werden können, wenn die-E
Option vongrep
verwendet wird oder mit(\+
Escapezeichen verwendet wird, wenn BRE (Basic Regex), dh nur regulärgrep
Die Zeichenklasse
[a-z,0-9,\"]
würde keines der Zeichen übereinstimmen zwischen[a-z]
,[0-9]
,,
oder"
. Dies ist möglicherweise nicht das, was Sie wollenNormalerweise wird die
grep
gesamte Zeile ausgegeben. Wenn Sie nur den übereinstimmenden Teil ausgeben möchten, verwenden Sie die-o
Option vongrep
Anhand Ihres Beispiels können Sie Folgendes tun:
-E
aktiviert ERE\b
Entspricht den String-Kanten und der Breite Nulldata=
passtdata=
buchstäblich[a-z0-9"]
jedes Zeichen von[a-z]
,[0-9]
, und"
.+
stimmt ein- oder mehrmals mit dem vorherigen Token übereinIhr aktuelles Muster selbst machen Sie es zu korrigieren, ohne
\b
diese Fehlalarme passen würde wiefoo fdata=2322ab
,data=12AB
und so weiter.Beispiel:
quelle
Eine andere Option ist die Verwendung von egrep:
egrep wird mit grep gebündelt, es ist nur ein Wrapper für grep:
Dies ist gut für den interaktiven Gebrauch. Allerdings würde ich in Skripten verwenden
grep -E
.quelle
egrep
. Es ist seit vielen Jahren zugunsten von veraltetgrep -E
. Wie in den POSIX-Spezifikationen angegeben, wird es weiterhin unterstützt und wird dies wahrscheinlich noch eine Weile sein, aber das aktuelle POSIX (und GNU)grep
wurde entwickelt, um das ältereegrep
und diefgrep
Varianten zu ersetzen, sodass es besser zu verwenden istgrep -E
undgrep -f
stattdessen.