GNU Awk 4.2 中 FS = " " 的行为是什么?
What is the behaviour of FS = " " in GNU Awk 4.2?
10 月的第一周,Arnold Robbins 在 GNU-announce、bug-gawk 和 comp.lang.awk mailing lists. It is available in http://www.skeeve.com/gawk/gawk-4.1.65.tar.gz[=] 中宣布 gawk 4.2.0 Beta 版现已推出 43=]1 并且他提到 这是一个主要版本,具有许多重要的新功能。
所以我通过 NEWS 文件深入研究了这些功能,并在这一点上停下来做一些测试:
Changes from 4.1.4 to 4.2.0
...
- Revisions in the POSIX standard remove the special case for POSIX
mode when FS = " " where newline was not a field separator. The code
and doc have been updated.
如果我没理解错的话,他讲的是GNU Awk User's Guide → 4.5.2 Using Regular Expressions to Separate Fields:
There is an important difference between the two cases of ‘FS = " "’ (a single space) and ‘FS = "[ \t\n]+"’ (a regular expression matching one or more spaces, TABs, or newlines). For both values of FS, fields are separated by runs (multiple adjacent occurrences) of spaces, TABs, and/or newlines. However, when the value of FS is " ", awk first strips leading and trailing whitespace from the record and then decides where the fields are.
也就是使用FS = " "
和FS = "[ \t\n]+"
的区别。
我运行新版本和运行用--posix
模式测试:
$ ./gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you
和我之前的awk (4.1.3) 相比,看不出有什么不同:
$ gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you
总而言之,我的问题是:在 GNU Awk 4.2 的 --posix
模式下,FS = " "
的行为有何不同? 什么已经完全改变了吗?
1 是的,我也觉得应该是4.2.tar.gz
,但是http://www.skeeve.com/gawk/gawk-4.2.tar.gz不存在
这是 4.2 的测试版,因此 built/named 与 4.1 相差。当它正式发布时,它将是 4.2.tar.gz.
我没有方便的 4.2 beta 来测试以下理论,但我认为关于默认 FS=" "
的公告意味着:
以前在 POSIX 中设置 FS=" "
意味着字段由全白 space 字符分隔 除了换行符 。另一方面,gawk 默认将换行符作为分隔符之一,您必须添加 --posix 才能获得 POSIX 行为。看:
$ gawk --version
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2)
$ printf 'a b\nc' | awk -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 3 1 <a>
1 3 2 <b>
1 3 3 <c>
$ printf 'a b\nc' | awk --posix -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 2 1 <a>
1 2 2 <b
c>
显然,现在 POSIX 标准已更新为在 FS=" "
时将 \n
包含在分隔符字符集中,因此 gawk 在 [=] 中不再需要在这方面表现不同33=] vs 非 posix 模式,而不是所有 POSIX awks 需要更新以一直默认情况下表现得像 gawk 一样。
您问题中的示例未对此进行测试,因为它使用 \n
作为 RS(默认值),因此无法测试当 \n
在记录中时会发生什么。设置RS="^$"
.
后再试
10 月的第一周,Arnold Robbins 在 GNU-announce、bug-gawk 和 comp.lang.awk mailing lists. It is available in http://www.skeeve.com/gawk/gawk-4.1.65.tar.gz[=] 中宣布 gawk 4.2.0 Beta 版现已推出 43=]1 并且他提到 这是一个主要版本,具有许多重要的新功能。
所以我通过 NEWS 文件深入研究了这些功能,并在这一点上停下来做一些测试:
Changes from 4.1.4 to 4.2.0
...
- Revisions in the POSIX standard remove the special case for POSIX mode when FS = " " where newline was not a field separator. The code and doc have been updated.
如果我没理解错的话,他讲的是GNU Awk User's Guide → 4.5.2 Using Regular Expressions to Separate Fields:
There is an important difference between the two cases of ‘FS = " "’ (a single space) and ‘FS = "[ \t\n]+"’ (a regular expression matching one or more spaces, TABs, or newlines). For both values of FS, fields are separated by runs (multiple adjacent occurrences) of spaces, TABs, and/or newlines. However, when the value of FS is " ", awk first strips leading and trailing whitespace from the record and then decides where the fields are.
也就是使用FS = " "
和FS = "[ \t\n]+"
的区别。
我运行新版本和运行用--posix
模式测试:
$ ./gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you
和我之前的awk (4.1.3) 相比,看不出有什么不同:
$ gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you
总而言之,我的问题是:在 GNU Awk 4.2 的 --posix
模式下,FS = " "
的行为有何不同? 什么已经完全改变了吗?
1 是的,我也觉得应该是4.2.tar.gz
,但是http://www.skeeve.com/gawk/gawk-4.2.tar.gz不存在
这是 4.2 的测试版,因此 built/named 与 4.1 相差。当它正式发布时,它将是 4.2.tar.gz.
我没有方便的 4.2 beta 来测试以下理论,但我认为关于默认 FS=" "
的公告意味着:
以前在 POSIX 中设置 FS=" "
意味着字段由全白 space 字符分隔 除了换行符 。另一方面,gawk 默认将换行符作为分隔符之一,您必须添加 --posix 才能获得 POSIX 行为。看:
$ gawk --version
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2)
$ printf 'a b\nc' | awk -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 3 1 <a>
1 3 2 <b>
1 3 3 <c>
$ printf 'a b\nc' | awk --posix -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 2 1 <a>
1 2 2 <b
c>
显然,现在 POSIX 标准已更新为在 FS=" "
时将 \n
包含在分隔符字符集中,因此 gawk 在 [=] 中不再需要在这方面表现不同33=] vs 非 posix 模式,而不是所有 POSIX awks 需要更新以一直默认情况下表现得像 gawk 一样。
您问题中的示例未对此进行测试,因为它使用 \n
作为 RS(默认值),因此无法测试当 \n
在记录中时会发生什么。设置RS="^$"
.