4.19 用awk实现head、tail和tac
只有通过实践才能够掌握文本处理的各种操作。这则攻略将帮助你综合运用之前已学过的一些命令。
4.19.1 预备知识
命令head
、tail
、uniq
和tac
都是逐行操作的。不管什么时候,只要我们需要进行逐行处理,我们都可以用awk
来解决。接下来让我们利用awk
模拟这些命令。
4.19.2 实战演练
看一看如何用不同的awk
命令来模拟诸如head
、tail
、tac
等命令。
模拟head
命令读取文件前10行并打印出来:
- $ awk 'NR <=10' filename
模拟tail
命令打印文件的后10行:
- $ awk '{ buffer[NR % 10] = $0; } END { for(i=1;i<11;i++) { print buffer[i%10] } }' filename
模拟tac
命令逆序打印输入文件的所有行:
- $ awk '{ buffer[NR] = $0; } END { for(i=NR; i>0; i--) { print buffer[i] } }' filename
4.19.3 工作原理
在head
的awk
实现中,我们打印输入流中行号小于或等于0的行。行号可以通过特殊变量NR
获得。
在tail
命令的实现中,我们使用了散列技术。数组buffer
的索引是由散列函数NR%10
决定的,其中变量NR
包含了当前行的行号,$0
包含了当前的文本行。因此,%
将所有余数相同的行都映射到一个特定的数组索引中。在END{ }
语句块中,对数组的10个索引进行迭代,并打印出对应的行。
在tac
命令的实现中,只是将所有的行存入一个数组中。当程序流程进入END{ }
语句块时,NR
存储着最后一行的行号。然后在for
循环中对NR
递减到1,并在每一次循环中打印存储的行。
4.19.4 参考
4.7节讲解了
awk
命令。3.14节讲解了
uniq
命令。2.8节讲解了
uniq
命令。4.15节讲解了
tac
命令。