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