awk split() 函数使用正则表达式还是精确的字符串常量?

awk split() function uses regular expression or exact string constant?

如果我们有 ip=192.168.0.1 并调用 split(ip, myArray, "."),myArray 将在位置 1 包含“192”,在位置 2 包含“168”,在位置 3 包含“0”,在位置 3 包含“1”位置 4.

我的问题是为什么 awk 不解释“.”作为 "any character" 正则表达式?

如果我想让 awk 解释“.”,我需要做什么?作为匹配的 "any character" 正则表达式?

此行为在所有 awk 实现中是否一致?

您应该使用 /./ 来区分正则表达式和静态字符串,以将每个字符用作分隔符:

$ echo 192.168.0.1 | awk '{ split([=10=],a,/./); print a[1] }'
$               # nothing here, every char is a delimiter.

这真是awk的黑角....

大约5年前我也有过同样的疑问。我作为bug提交,和一个gawk的开发者谈过,终于搞清楚了。这是一个“特征”。

这是门票:https://lists.gnu.org/archive/html/bug-gawk/2013-03/msg00009.html

split(str, array, magic)

对于magic:

  • 当你使用一个非空字符串(由""引用)"..."时,awk会检查字符串的长度,如果是单个字符,它会用作文字字符串(他们称之为分隔符)。但是,如果它比 1 长,它将被视为动态正则表达式。

  • 当您使用静态正则表达式时,这意味着在格式 /.../ 中,无论表达式有多长,它都将始终被视为正则表达式。

即:

"."  - literal "." (period)
"["  - literal "["
"{"  - literal "{"
".*" - regex
/./  - regex
/whatever/ -regex

如果您希望 awk 将 .(period) 视为正则表达式元字符,您应该使用 split(foo,bar,/./) 但是如果您按任何字符拆分,您可能会得到空数组,如果这是您真正想要的。