8Linux操作命令sort,uniq,join

  • sort 命令
  • uniq 命令
  • join 命令

sort 命令

同文本文件打交道时,总避不开排序,那是因为对于文本处理任务而言,排序(sort)可以起到不小的作用。sort 命令能够帮助我们对文本文件和 stdin 进行排序操作。通常,它会结合其他命令来生成所需要的输出。

(1)命令格式

1
sort [选项] [文件名]
  • (2)常用参数
参数 描述
-n 基于字符串的长度来排序,使用此选项允许根据数字值排序,而不是字母值
-k 指定排序关键字

-b 默认情况下,对整行进行排序,从每行的第一个字符开始。这个选项导致 sort 程序忽略每行开头的空格,从第一个非空白字符开始排序
-m |只合并多个输入文件
-r |按相反顺序排序,结果按照降序排列,而不是升序
-t |自定义分隔符,默认为制表符

(3)常用范例

  • 例一:列出/usr/share/目录下使用空间最多的前 10 个目录文件,可以使用如下命令:
1
du -s /usr/share/* | sort -nr | head -10

du -s /usr/share/* 命令显示/usr/share/目录下所有文件和目录的磁盘使用空间,目录包含目录下的子目录和文件

  • 例二:ls 命令能显示目录下文件的详细信息,包含空间使用大小,但与 du 命令不同的是,ls 命令不计算目录下的子目录和文件的大小。ls 显示格式如下:
1
-rwxrwxrwx   1  root   root  542  11 月   29  test.php

现在想要对 ls 命令输出信息中的空间使用大小字段进行排序,可以使用如下命令:

1
ls -l /usr/bin/ | sort -nr -k 5 | head -10
  • 例三:首先来看下下面的例子:

由于 11 由 1 开始,比 5 小,所以排在 5 的前面。这时排序可以通过自定义排序字段来排序。使用下面的命令就可以解决。

1
sort  -k 1,1  -k 2n data.txt

第一个-k 选项指明只对第一个字段排序,1,1 意味着“始于并且结束于第一个字段”。 第二个-k 选项 2n 表示对第二个字段按数值排序。 还有一种格式,如-k 3.4n,表示始于第三个字段的第四个字符,按数值排序。

-k 选项的语法格式如下:

[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

这个语法格式可以被其中的逗号(“,”)分为两大部分,Start 部分和 End 部分。

先给你灌输一个思想,那就是“如果不设定 End 部分,那么就认为 End 被设定为行尾”。这个概念很重要的,但往往你不会重视它。

Start 部分也由三部分组成,其中的 Modifier 部分就是类似 n 和 r 的选项部分。我们重点说说 Start 部分的 FStart 和 CStart。 FStart.CStart,其中 FStart 就是表示使用的域,而 CStart 则表示在 FStart 域中从第几个字符开始算“排序首字符”。CStart 是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 5 就是省略了 CStart 的例子。

同理,在 End 部分中,你可以设定 FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将 CEnd 设定为 0(零),也是表示结尾到“域尾”。

uniq 命令

uniq 命令经常和 sort 命令结合在一起使用。uniq 从标准输入或单个文件名参数接受数据有序列表,默认情况下,从数据列表中删除任何重复行。

uniq 只能用于排过序的数据输入,因此,uniq 要么使用管道,要么将排过序的文件作为输入,并总是以这种方式与 sort 命令结合起来使用。

uniq 命令是 unique 的缩写。

(1)命令格式

1
uniq [选项] [文件名]

(2)常用参数

参数 描述
-c 在每行前加上表示相应行目出现次数的前缀编号
-d 只输出重复的行
-u 只显示唯一的行
-D 显示所有重复的行
-f 比较时跳过前 n 列
-i 在比较的时候不区分大小写
-s 比较时跳过前 n 个字符
-w 对每行第 n 个字符以后的内容不作对照

(3)常用范例

  • 例一:找出/bin 目录和/usr/bin 目录下所有相同的命令,可以使用如下命令:
1
ls /bin /usr/bin  | sort | uniq -d
  • 例二:现有文件内容如下,红色方框里的内容表示区号,现在要统计出各个区号的总人数。 img

实现思路:首先按区号对每行信息排序,然后使用 uniq 命令对区号进行重复行统计。使用命令如下:

1
sort -k 4.1n,4.1n student.txt | uniq -c -f 3 -w 2

sort -k 4.1n,4.1n 表示对第四个字段的第一个字符按数值排序。

uniq -c -f 3 -w 2 中-f 3 表示跳过前三列的比较,那么现在只剩下最后一列,-w 2 表示第 2 个字符后的内容不做比较,为什么是 2 呢,因为跳过前三列时并没有跳过最后一列前面的空格分隔符,区号前都还有一个空格。

join 命令

join 命令类似于 paste,它会往文件中添加列,但是它使用了独特的方法来完成。一个 join 操作通常与关系型数据库有关联,在关系型数据库中来自多个享有共同关键域的表格的数据结合起来,得到一个期望的结果。这个 join 命令执行相同的操作,它把来自于多个基于共享关键域的文件的数据结合起来。

通俗地说,就是将两个文件中指定栏位相同的行连接起来,即按照两个文件中共同拥有的某一列,将对应的行拼接成一行。

(1)命令格式

join [选项] 文件 1 文件 2

(2)常用参数

参数 描述
-j FIELD 等同于 -1 FIELD -2 FIELD,-j 指定一个域作为匹配字段
-1 FIELD 以 file1 中 FIELD 字段进行匹配
-2 FIELD 以 file2 中 FIELD 字段进行匹配
-t 自定义分隔符,默认为制表符

(3)常用范例

  • 例一:将两个文件中的第一个字段作为匹配字段,连接两个文件,可以使用如下命令:
1
join  a.txt  b.txt
  • 例二:指定两个文件的第三个字段为匹配字段,连接两个文件,可以使用如下命令:
1
join  -1 3 -2 3 c.txt d.txt

,一开始对 a.txt 和 b.txt 文件内容执行 join 命令时报错,这是因为 join 命令跟 uniq 命令一样,只能用于排过序的数据。