请注意,根据 POSIX,RS
它被定义为单个字符而不是正则表达式。
字符串值的第一个字符RS
应为输入记录分隔符;<newline> 默认情况下。如果RS
包含多个字符,则结果未指定。如果RS
为 null,则记录由 <newline> 加上一个或多个空行组成的序列分隔,前导或尾随空行不应导致输入的开头或结尾处为空记录,并且 <newline> 应始终是一个字段分隔符,不管 的值FS
是什么。
来源:Awk Posix 标准
这意味着RS=" *, *"
导致未定义的行为。
其他实现 POSIX 扩展的 awk 版本可能对RS
代表的含义有不同的方法。例如 GNU awk 和 mawk。两者都实现RS
为正则表达式,但两种实现略有不同。<asterisk> 的使用总结如下:
| RS | awk (posix) | gawk | mawk |
|------+--------------+------------------+------------------|
| "*" | "<asterisk>" | "<asterisk>" | "<asterisk>" |
| "*c" | undefined | "<asterisk>c" | undefined |
| "c*" | undefined | "","c","ccc",... | "","c","ccc",... |
c is any character
以上应该解释 OP 的错误,因为RS="*, *"
它是根据 mawk 的无效正则表达式。
$ echo "abc" | ./mawk '/*c/'
mawk: line 1: regular expression compile failed (missing operand)
GNU awk:GNU awk的手册说明如下:
使用 时gawk
,的值RS
不限于一个字符的字符串。它可以是任何正则表达式(参见Regexp)。(ce) 一般情况下,每条记录在下一个匹配正则表达式的字符串处结束;下一条记录从匹配字符串的末尾开始。
来源:GNU awk 手册
为了理解 <asterisk> 在 GNU awk 正则表达式中的用法,我们发现:
<asterisk>*
此符号表示前面的正则表达式应根据需要重复多次才能找到匹配项。例如,ph*
将*
符号应用于前面的符号并查找一个后跟任意数量的sh
的匹配项。仅当不存在s 时,这也匹配。p
h
p
h
有两个微妙的点可以理解如何*
工作。首先,*
仅适用于单个前面的正则表达式组件(例如,在 中ph*
,它仅适用于h
)。要*
使其应用于更大的子表达式,请使用括号:(ph)*
匹配ph
、、、phph
等等phphph
。
其次,*
找到尽可能多的重复。如果要匹配的文本是phhhhhhhhhhhhhhooey
,则ph*
匹配所有的h
s。
来源:GNU 正则表达式运算符
然而,必须提到的是:
在POSIX awk和 gawk中*
,+
和?
运算符代表它们自己,当它们之前的正则表达式中没有任何内容时。例如,/+/
匹配文字加号。但是,许多其他版本的 awk 将这种用法视为语法错误。
来源:GNU 正则表达式运算符
因此,设置RS="*, *"
, 意味着它将匹配字符串"*,"
, "*, "
, "*, "
, ...
$ echo "a,b, c" | awk 'BEGIN{RS="*, *"}1'
a,b, c
$ echo "a*,b, c" | awk 'BEGIN{RS="*, *"}1'
a
b, c
mawk: GNU awk 的手册说明如下:
12.多行记录
由于mawk
解释RS
为正则表达式,多行记录很容易。
来源:man mawk
但
11. 拆分字符串、记录和文件
awk 程序使用相同的算法将字符串拆分为数组
split()
,将记录拆分为字段FS
。 mawk 使用基本相同的算法将文件拆分为RS
.
Split(expr,A,sep)
工作方式如下:
- <剪辑>
- 如果
sep = " "
(单个空格),则 <SPACE> 被从 的前后修剪expr
,sep
变成 <SPACE>。mawk 将 <SPACE> 定义为正则表达式/[ \t\n]+/
。否则sep
被视为正则表达式,除了长度为 1 的字符串的元字符被忽略,例如, split(x, A, "*")
并且split(x, A, /\*/)
是相同的。
- <剪辑>
来源:man mawk
该手册没有提到应如何解释以元字符开头的正则表达式(例如“*c”)
注意:在 GNU awk 部分中,我通过了 POSIX awk,因为根据 POSIX,形式的正则表达式"*, "
会导致未定义的行为。(这与定义无关,RS
反正RS
不是 POSIX awk 中的 ERE)
awk 实用程序应使用扩展正则表达式表示法(请参阅 XBD扩展正则表达式)
来源:Awk Posix 标准
和
*+?{
<asterisk>、<plus-sign>、<question-mark> 和 <left-brace> 应该是特殊的,除非在括号表达式中使用(参见 RE 括号表达式)。以下任何用途都会产生未定义的结果:
- 如果这些字符首先出现在 ERE中,或者紧跟在未转义的 <vertical-line>、<circumflex>、<dollar-sign> 或 <left-parenthesis> 之后
- 如果 <left-brace> 不是有效区间表达式的一部分(请参阅 EREs Matching Multiple Characters)
来源:POSIX 扩展正则表达式