加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

macos – 在awk字段分隔符更改后重新评估记录中的字段

发布时间:2020-12-13 23:25:49 所属栏目:Linux 来源:网络整理
导读:(这是我在这里发表的第一篇文章,如果我以错误的方式提问,请原谅我.) 我在OSX Maverick上学习awk.我在awk上经历了this tutorial. 我试图在该教程中重现与awk_example4a.awk类似的内容. 所以我想出了这个awk程序/脚本/参数(不知道你叫什么?): BEGIN { i=1 }{
(这是我在这里发表的第一篇文章,如果我以错误的方式提问,请原谅我.)

我在OSX Maverick上学习awk.我在awk上经历了this tutorial.

我试图在该教程中重现与awk_example4a.awk类似的内容.

所以我想出了这个awk程序/脚本/参数(不知道你叫什么?):

BEGIN { i=1 }
{
    print "Line " i;
    print "$1 is " $1,"n$2 is " $2,"n$3 is " $3;
    FS=":";
    $0=$0;
    print "With the new FS - line " i;
    print "$1 is " $1,"n$3 is " $3;
    FS=" ";
    i++;
}

输入文件如下所示:

A1 B1:B2 C2
A1:A2 B2:B3 C3

我想要做的是先用默认的FS(空格)处理每一行/记录,然后用新的FS(“:”)重新处理它,然后在转到下一条记录之前恢复默认的FS .

根据教程,$0 = $0应该使用新的字段分隔符来重新评估字段,因此据说给我一个如下所示的输出:

Line 1
$1 is A1 
$2 is B1:B2 
$3 is C2
With the new FS - line 1
$1 is A1 B1
$2 is B2 C2
$3 is
Line 2
$1 is A1:A2 
$2 is B2:B3 
$3 is C3
With the new FS - line 2
$1 is A1
$2 is A2 B2
$3 is B3 C3

但相反,我得到:

Line 1
$1 is A1 
$2 is B1:B2 
$3 is C2
With the new FS - the line 1
$1 is A1 
$2 is B1:B2 
$3 is C2
Line 2
$1 is A1:A2 
$2 is B2:B3 
$3 is C3
With the new FS - the line 2
$1 is A1:A2 
$2 is B2:B3 
$3 is C3

即FS更改后,字段尚未重新评估.

因此,如果$0 = $0不起作用(也不做$1 = $1; $2 = $2),我如何使用不同的FS重新评估同一行?

谢谢.

解决方法

TL; DR:

FreeBSD / OS X awk在当前记录处理完成之前不会对FS(字段分隔符)应用更改 – 这种行为实际上是POSIX强制的(见下文).

解决方法:不要更改FS并使用函数split()代替:

{
    print "Line " ++i
    print "$1 is " $1 "n$2 is " $2 "n$3 is " $3
    split($0,flds,":")   # split current line by ':' into array `flds`
    print "With the new FS - line " i
    print "field1 is " flds[1] "nfield2 is " flds[2] "nfield3 is " flds[3]
}

>注意如何在数值上下文中依赖未初始化的变量默认为0来消除BEGIN块.
>,实例已从print语句中删除,因为每个实例都会插入一个空格(输出字段分隔符的默认值OFS),在这种情况下不需要.
>鉴于这些陈述是换行符,不需要终止它们.

请继续阅读,了解有趣的多平台兼容性详细信息.

POSIX spec. for awk州(强调我的):

Before the first reference to a field in the record is evaluated,the record shall be 
split into fields,according to the rules in Regular Expressions,**using the value of FS that was current at the time the record was read**.

关于将新值分配给$0或特定字段,相同的源指出:

The symbol $0 shall refer to the entire record; setting any other field causes 
the re-evaluation of $0. Assigning to $0 shall reset the values of all other
fields and the NF built-in variable.

换句话说:假设重新赋值情况没有另外说明,则只能引用POSIX规范中给定FS值的范围.要求它对于给定的输入记录是恒定的.
肯定存在歧义,如果规范肯定会有所帮助.解决了 – 那就是说,保守而且更安全的解释是假设一个恒定的同时处理一个给定记录的FS.

因此,FreeBSD / OS X awk是模型公民,而GNU awk和mawk通过不按规则播放并将FS更改应用于重新分配到$0或任何特定字段的当前记录来提供更大的灵活性.

但请注意,GNU awk(自v4.1.1起)甚至不会使用–posix选项更改该行为,该选项的明确意图是导致符合POSIX的行为.如果我正在阅读POSIX规范.正确(告诉我我是否),这应该被视为一个错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读