gawk 和 mawk 在字段分隔符方面有什么区别?

Ang*_*elo 9 awk

gawk 和 mawk 在字段分隔符方面有什么区别?特别是,我想弄清楚这里发生了什么:

\n

莫克:

\n
$ echo "100+50\xc2\xb020.5" | mawk -F '[+\xc2\xb0.]' '{ print $1" - "$2" - "$3" - "$4" - "$5; }'\n100 - 50 -  - 20 - 5\n
Run Code Online (Sandbox Code Playgroud)\n

呆呆地:

\n
$ echo "100+50\xc2\xb020.5" | gawk -F '[+\xc2\xb0.]' '{ print $1" - "$2" - "$3" - "$4" - "$5; }'\n100 - 50 - 20 - 5 -\n
Run Code Online (Sandbox Code Playgroud)\n

看起来 mawk 正在以某种方式引入一个额外的字段。什么是正确的行为?

\n

Ste*_*itt 21

要了解此处发生的情况,请查看作为 AWK 输入提供的字节:

\n
$ od -t x1 <<<"100+50\xc2\xb020.5"\n0000000 31 30 30 2b 35 30 c2 b0 32 30 2e 35 0a\n0000015\n
Run Code Online (Sandbox Code Playgroud)\n

在UTF-8中,\xe2\x80\x9c\xc2\xb0\xe2\x80\x9d是一个多字节字符,用0xC2 0xB0表示。MAWK 不\xe2\x80\x99t 支持多字节字符,因此它将作为字段分隔符提供的正则表达式视为匹配四个字节 0x2B (\xe2\x80\x9c+\xe2\x80\x9d)、0xC2 ( \xe2\x80\x9c\xc2\xb0\xe2\x80\x9d 第一部分)、0xB0(\xe2\x80\x9c\xc2\xb0\xe2\x80\x9d 第二部分)和 0x2E(\xe2\x80\ x9c.\xe2\x80\x9d)。它们在输入字符串中匹配四次,产生五个字段:

\n
    \n
  • \xe2\x80\x9c100\xe2\x80\x9d
  • \n
  • \xe2\x80\x9c50\xe2\x80\x9d
  • \n
  • 空字符串(0xC2 和 0xB0 之间)
  • \n
  • \xe2\x80\x9c20\xe2\x80\x9d
  • \n
  • \xe2\x80\x9c5\xe2\x80\x9d
  • \n
\n

GAWK 会考虑当前语言环境,默认支持多字节字符,因此它将 \xe2\x80\x9c\xc2\xb0\xe2\x80\x9d 作为字符进行匹配,并找到四个字段。-b可以通过使用该选项或使用 切换到非多字节区域设置来禁用此功能LC_ALL=C

\n


JJo*_*oao 15

正如 StephenKitt 和评论中明智地解释的那样,\xc2\xb0多字节 char\nis 在[\xc2\xb0]上下文中被分割......

\n

解决这个问题的一种方法是使用“or”正则表达式运算符:

\n
awk -F '[+.]|\xc2\xb0' ...\n
Run Code Online (Sandbox Code Playgroud)\n