理解在AWK命令中使用的SUB

3
我需要了解这个命令是如何工作的:

awk 'BEGIN{while(a++<30)s=s " "};{sub(/^.{6}/,"&" s)};l' myfile

我理解第一部分(BEGIN{}部分的表达式)是创建一个长度为30个字符的空格字符串。但是我不理解第二部分(sub)的作用。 sub 命令将最近生成的字符串 "s" 添加到'myfile'的第6列。但是,就我所看到的命令而言,搜索模式 /^.{6}/ 应该查找以一个字符 (.) 开始,然后 {6} 个字符,然后将其替换为添加空格的字符串!
请帮助我更好地理解这个问题?

去掉空语句(多余的分号),脚本末尾应该是数字一(1),而不是字母el(l)。 - Ed Morton
2个回答

3

这与第六列无关,也不是在寻找一个字面上的{6}。

花括号表示“前面的模式中有这么多个”(如果您使用--posix或--re-interval调用GNU awk)。

因此,此模式:

/^.{6}/

等同于这个:

/^....../

它的作用是在前6个字符后添加字符串s,这6个字符可以是任何字符。
下面的awk命令会执行类似的操作:
awk 'BEGIN{while(a++<30)s=s " "} {print substr($0, 1, 6) s substr($0, 7)}' myfile

1
最近的gawk发行版默认启用了RE-intervals,因此只有在您使用旧版本的gawk时才需要--re-interval(而且您应该避免使用--posix)。 - Ed Morton
@EdMorton 感谢您的建议,我正在CentOS 6.4上使用GNU awk 3.1.7,并且我必须使用该标志。什么样的gawk分发被视为最近的并默认启用它? - Bill Karwin
啊哈,谢谢。企业级Linux发行版往往更新某些软件包的速度较慢。 - Bill Karwin
抱歉如果这个问题听起来太简单了。但我认为awk只是gawk的符号链接。那么为什么需要在上面的命令中指定gawk呢? 另外,我尝试在我的OSX终端(在-bash模式下)运行代码(使用gawk),但找不到它。 - user2395215
1
@user2395215,OS X基于FreeBSD UNIX,我相信它使用大多数工具的UNIX实现,而不是GNU工具。 - Bill Karwin
显示剩余2条评论

2

请参考@BillKarwin的答案了解它正在做什么,同时查看下面的第二个awk脚本以更简明地实现:

$ cat file
abcdefghi

$ awk 'BEGIN{while(a++<30)s=s " "} {sub(/^.{6}/,"&" s)} 1' file
abcdef                              ghi

$ awk '{printf "%-36s%s\n",substr($0,1,6),substr($0,7)}' file
abcdef                              ghi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接