awk学习笔记(6) - 过滤及排序

过滤掉文本中的重复行

测试文件还是用之前的arr.dat,用下面的命令可以很轻松的解决


  1. sort -u arr.dat 

输出结果:


  1. 1005 8:12 
  2. 1005 8:13 
  3. 1006 7:45 
  4. 1008 8:01  
  5. 1012 7:46  
  6. 1025 7:27 
  7. 1028 7:49  
  8. 1029 7:57  
  9. 1034 7:26  
  10. 1042 7:59 
  11. 1051 7:51 
  12. 1052 8:05  
  13. 1101 7:32 

这并没有用到awk,如果将问题再进一步,如何过滤掉第一列重复的数据?


  1. awk '{print $1}' arr.dat|sort -u 

输出结果:


  1. 1005 
  2. 1006 
  3. 1008 
  4. 1012 
  5. 1025 
  6. 1028 
  7. 1029 
  8. 1034 
  9. 1042 
  10. 1051 
  11. 1052 
  12. 1101 

可以看到,第一列所有的重复数据都已经过滤掉了。

上面的程序用到了新的东西:管道符(|)

管道会将其左边的输出传到右边作为输入。在awk程序中有两种使用管道的语法,如下:

  1. awk output 指令 | "Shell 接受的命令"
  2. "Shell 接受的命令" | awk input 指令

上面的例子就是语法1的例子,awk '{print $1}' arr.dat会输出arr.dat的第一列,它会传给sort -u去重和排序,sort是shell命令。

对于语法2,看下面的例子:


  1. awk 'BEGIN {"date"|getline;print $1}' 

输出结果:


  1. 2012年10月20日 

好消息,在awk中输入指令只有一个:getline

实际上,awk程序是可以接收来自shell的输出的,可以看下面的例子:


  1. cat arr.dat|awk '{print $1}' 

上面的语句跟下面的是等价的:


  1. awk '{print $1}' arr.dat 

都是输出文件的第一列。

顺便也学习一下sort的用法:


  1. sort -k2,2 -u -r arr.dat 

输出结果:


  1. 1005 8:13 
  2. 1005 8:12 
  3. 1052 8:05  
  4. 1008 8:01  
  5. 1042 7:59 
  6. 1029 7:57  
  7. 1051 7:51 
  8. 1028 7:49  
  9. 1012 7:46  
  10. 1006 7:45 
  11. 1101 7:32  
  12. 1025 7:27 
  13. 1034 7:26  

上面的sort语句是将第二列去重并倒排序,

-k2,2指代的是取第二列,逗号前的2是域起点,后的2是域终点;

-u是去重

-r是倒序

如果不用sort怎么去重呢?试试下面的程序:


  1. awk '!a[$1]++' arr.dat 

上面的语句在单引号之内只有一个表达式,没有输出,在awk中会默认输出整行。a数组以第一列的值为键,如果第二行有跟第一列一样的值,则 a[$1]++后的结果是1,再取反,就成了0,就不会再输出整行了,换句话说就是,第二个重复的列将不再输出。这也起到了去重的作用。

顺便说一下,上面这种方法不会更改数据的顺序,当我们需要保持行记录的顺序时,可以用这种办法。










本文转自 ustb80 51CTO博客,原文链接:http://blog.51cto.com/ustb80/1033624,如需转载请自行联系原作者
上一篇:Android官方开发文档Training系列课程中文版:数据存储之键值对序列存储


下一篇:cmd 命令行下复制和粘贴