Ich denke nicht, dass es um den regulären Ausdruck geht, sondern darum, wie mit der Zeichenfolge in doppelten Anführungszeichen umgegangen wird. C-artige Escapezeichen (wie \n
) werden in awk-Zeichenfolgen interpretiert, und gawk und mawk behandeln ungültige Escapezeichen unterschiedlich:
$ mawk 'BEGIN { print "\."; }'
\.
$ gawk 'BEGIN { print "\."; }'
gawk: cmd. line:1: warning: escape sequence `\.' treated as plain `.'
.
Das heißt, mawk scheint den Backslash unverändert zu lassen, während gawk ihn entfernt (und sich zumindest in meiner Version beschwert). Die tatsächlich verwendeten regulären Ausdrücke sind also unterschiedlich : In gawk ist der reguläre Ausdruck .pdf
, der natürlich übereinstimmt /pdf
, da der Punkt mit einem einzelnen Zeichen übereinstimmt, während in mawk Ihr regulärer Ausdruck ist \.pdf
, in dem der Punkt maskiert und buchstäblich abgeglichen wird.
Im Handbuch von GNU awk wird ausdrücklich erwähnt, dass es nicht portabel ist, einen Backslash vor einem Zeichen ohne definierte Backslash-Escape-Sequenz zu verwenden (siehe Kasten "Backslash vor regulären Zeichen"):
Wenn Sie einen Backslash in eine Zeichenfolgenkonstante vor etwas einfügen, das nicht zu den zuvor aufgeführten Zeichen gehört, lässt POSIX awk das, was passiert, absichtlich undefiniert. Es gibt zwei Möglichkeiten:
Den Backslash ausziehen
Dies ist, was BWK awk und gawk beide tun. Zum Beispiel "a\qc"
ist das gleiche wie "aqc"
.
Lassen Sie den Backslash in Ruhe
Einige andere awk-Implementierungen tun dies. In solchen Implementierungen ist das Tippen "a\qc"
dasselbe wie das Tippen "a\\qc"
.
Ich gehe davon aus, dass Sie möchten, dass der Punkt in der Regex maskiert wird, also sind die sicheren Wege entweder $NF ~ "\\.pdf"
oder $NF ~ /\.pdf/
(da mit dem Regex-Literal die Escape-Zeichen /.../
nicht "doppelt verarbeitet" werden).
Der POSIX-Text weist auch auf die doppelte Verarbeitung der Escapezeichen hin:
Wenn der rechte Operand [von ~
oder !~
] ein anderer Ausdruck als das lexikalische Token ERE ist, wird der Zeichenfolgenwert des Ausdrucks als erweiterter regulärer Ausdruck interpretiert, einschließlich der oben beschriebenen Escape-Konventionen. Beachten Sie, dass dieselben Escape-Konventionen auch bei der Bestimmung des Werts eines Zeichenfolgenliterals (des lexikalischen Token STRING) angewendet werden müssen und daher ein zweites Mal angewendet werden müssen, wenn in diesem Zusammenhang ein Zeichenfolgenliteral verwendet wird .
Das funktioniert also sowohl bei Gawk als auch bei Mawk:
$ ( echo .pdf; echo /pdf ) |
awk '{ if ($0 ~ "\\.pdf") print " match: " $0; else print "no match: " $0; }'
match: .pdf
no match: /pdf
wie das:
$ ( echo .pdf; echo /pdf ) |
awk '{ if ($0 ~ /\.pdf/) print " match: " $0; else print "no match: " $0; }'
match: .pdf
no match: /pdf
/\[/
,\[
bleibt wie es ist, und dann macht der Backslash den[
Verlust seiner besonderen Eigenschaften während der Regex-Verarbeitung? Damit die Absicht tatsächlich ist, dass/\[/
das gleiche wie\[
in grep etc tut ?[.]
ist eine besser lesbare Möglichkeit, einen Punkt abzugleichen, wie @mosvy unten erwähnt.Wie Sie der Tabelle hier entnehmen können, ist in einem regulären Ausdruck in awk ein Backslash, gefolgt von bis zu 3 Oktalstellen, ein weiterer Backslash oder einer der folgenden Werte nicht
["/abfnrtv]
definiert.Am besten schreiben Sie,
[.]
anstatt\.
ein Literal zu schreiben.
.Beachten Sie, dass in diesem Fall das
mawk
Verhalten von der allgemeinen Praxis abweicht. Während alleawk
mir bekannten Implementierungen Sie entkommen lassen\.
,\+
können Sie\*
in einem Regex-Literal (/foo\.bar/
) nurmawk
innerhalb einer Zeichenfolge, die als regulärer Ausdruck verwendet wird ($0~"foo\.bar"
), dasselbe tun .quelle
/proc
odersock_diag
direkt von Perl oder Python möglicherweise eine bessere Idee als das Parsen der Ausgabe vonlsof
.echo '/pdf \.pdf' |mawk '$1 ~ $2 { print "match"; }'
\[
,\*
oder\(
als etwas anderes als entkommen Sonderzeichen?Verwenden Sie das richtige Werkzeug für den Job. Sie haben diese 2 Ausdrücke:
In beiden Fällen sind die Muster jedoch wörtliche Zeichenfolgen. Also kein Grund, sich überhaupt mit Regex-Matching zu beschäftigen, verwenden Sie einfach den wörtlichen String-Matching:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_13
quelle
Wie in vielen anderen Sprachen
\x
hat eine andere Bedeutung in Zeichenfolgen oder in regulären Ausdrücken. Sie können entweder verwendenoder
Die Saite
"\.pdf"
ist nur eine seltsame Art zu sagen".pdf"
quelle