题目
使用awk文本处理工具将一个名为c的文件按照同名字段进行合并,c的内容如下所示:
192.168.1.1: httpd
192.168.1.1: tomcat
192.168.1.2: httpd
192.168.1.2: postfix
192.168.1.3: mysqld
192.168.1.4: httpd
示例输出:
192.168.1.1: httpd tomcat
192.168.1.2: httpd postfix
192.168.1.3: mysqld
192.168.1.4: httpd
解答
awk 'BEGIN{FS=":";OFS=":"}{a[$1]=a[$1] $2}END{for(v in a)print v,a[v]}' c
解释:
-
BEGIN{}
分别定义了输入分隔符和输出分隔符 -
中间BODY部分的
{}
展示了一个数组赋值操作。数组 a 的索引是每行的第一个字段(IP 地址),值是不断追加的第二个字段(服务名)。注意,这里使用了a[$1] $2
的形式来追加服务名,意味着如果a[$1]
已经有值(即之前已经遇到过相同的 IP 地址),那么新的服务名会被追加到已存在的值之后,前面会自动加上一个空格作为分隔符。比如:
扫描到第一行时,$1=192.168.1.1
,$2=httpd
,a[$1]=a[$1] $2 ==> a[192.168.1.1] = httpd
扫描到第二行时,$1=192.168.1.1
,$2=tomcat
,a[$1]=a[$1] $2 ==> a[192.168.1.1] = httpd tomcat
以此类推 -
END{}
是在处理完所有输入行之后执行。这里是遍历数组 a,其中 v 是数组的索引(IP 地址),a[v] 是对应的值(所有相关服务名)。对于数组中的每个元素,都打印出其索引和值