shell快速排序、去重文本内容

时间:2021-07-26 12:21:36

    逛ChinaUnix论坛,常常可看到到日经帖,怎么快速排序一个文本内容,或者计算某行出现次数。这些问 题大部分都可以通过简单的sort、uniq命令来解决。

首先准备两个文本

cat file1:

Boys in Company C       :HK     :192    :2192

Alien                   :HK     :119    :1982

The Hill                :KL     :63     :2972

Aliens                  :HK     :532    :4892

Star Wars               :HK     :301    :4102

A Few Good Men          :KL     :445    :5851

Toy Story               :HK     :239    :3972

cat file2:

boy took bat home

boy took bat home

girl took bat home

boy took bat home

boy took bat home

dog brought hat home

dog brought hat home

dog brought hat home



sort:

将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。


常用的几个参数: sort -mnrtku

m:合并文件

n:按数值大小来排序

r:逆序排

t:自定义分隔符来划分域

k:选定域来排序

u:全文本去重

域相当于列

1、sort -m file1 file2 合并两个文件

Boys in Company C       :HK     :192    :2192

Alien                   :HK     :119    :1982

boy :took :bat :home

boy :took :bat :home

girl :took :bat :home

boy :took :bat :home

boy :took :bat :home

dog :brought :hat :home

dog :brought :hat :home

dog :brought :hat :home

The Hill                :KL     :63     :2972

Aliens                  :HK     :532    :4892

Star Wars               :HK     :301    :4102

A Few Good Men          :KL     :445    :5851

Toy Story               :HK     :239    :3972

2、-n参数是有时候会排序出现10比2小的情况,因为sort是直接比较第一个字符,所以要使用-n来进行数值比较。

3、-r参数,sort排序小的排上,大的在下,有时候行数很多,你只想知道最大的就可以sort -r |more就可以了。

4、-t参数,选定分隔域符号,这个常常和-k参数一起用,如我们需要按file1的第三列的数值大小排序

sort -n -t:-k3 file1

The Hill                :KL     :63     :2972

Alien                   :HK     :119    :1982

Boys in Company C       :HK     :192    :2192

Toy Story               :HK     :239    :3972

Star Wars               :HK     :301    :4102

A Few Good Men          :KL     :445    :5851

Aliens                  :HK     :532    :4892

如果不加-n参数

sort  -t: -k3 file1  

Alien                   :HK     :119    :1982

Boys in Company C       :HK     :192    :2192

Toy Story               :HK     :239    :3972

Star Wars               :HK     :301    :4102

A Few Good Men          :KL     :445    :5851

Aliens                  :HK     :532    :4892

The Hill                :KL     :63     :2972

隐藏属性,sort的输出都是标准屏幕输出,如果我们要输出到源文件,使用重定向就会杯具。。

sort file1>file1;cat file1,你会得到一个空文件。这时候要使用-o参数来实现这个功能。

sort file1 -o file1


uniq:

   这个命令读取输入文件,并比较相邻的行。在正常情况下,第二个及以后更多个重复行将被删去,行比较是根据所用字符集的排序序列进行的。该命令加工后的结果写到输出文件中。输入文件和输出文件必须不同。如果输入文件用“- ”表示,则从标准输入读取。

它与sort -u的区别在于,sort -u是全文本去重,而uniq是比较相邻行,将第二个及以后更多重复行删去。

语法:uniq [-cdu][-f<栏位>][-s<字符位置>][-w<字符位置>][--help][--version][输入文件][输出文件]

补充说明:uniq可检查文本文件中重复出现的行列。

参数:
-c或--count   在每列旁边显示该行重复出现的次数。
-d或--repeated   仅显示重复出现的行列。
-f<栏位>或--skip-fields=<栏位>   忽略比较指定的栏位。
-s<字符位置>或--skip-chars=<字符位置>   忽略比较指定的字符。
-u或--unique   仅显示出一次的行列。
-w<字符位置>或--check-chars=<字符位置>   指定要比较的字符。
--help   显示帮助。
--version   显示版本信息。

常用的是-c参数,显示行的重复出现次数。

uniq -c file2

      2 boy :took :bat :home

      1 girl :took :bat :home

      2 boy :took :bat :home

      3 dog :brought :hat :home

但由于是只比较相邻行,所以还是配合sort先排序一下:

 sort file2 |uniq -c

      4 boy :took :bat :home

      3 dog :brought :hat :home

      1 girl :took :bat :home

这样才得到我们想要的结果。

最后再把这两个文件合并的漂亮一点:

 sort -m file1 file2 |sort |uniq -c |sed 's/ //g'|awk -F ":" '{printf ("%-10s %10s %10s %10s\n",$1,$2,$3,$4)}'

1AFewGoodMen         KL        445       5851

1Alien             HK        119       1982

1Aliens            HK        532       4892

1BoysinCompanyC         HK        192       2192

4boy             took        bat       home

3dog          brought        hat       home

1girl            took        bat       home

1StarWars          HK        301       4102

1TheHill           KL         63       2972

1ToyStory          HK        239       3972

感觉还是很坑爹。。

1、sort -m居然只合并,没有排序

2、printf的对齐,看上去这么怪。。

本文出自 “DanielQu” 博客,请务必保留此出处http://qujunorz.blog.51cto.com/6378776/1564003