linux环境下使用sort命令完成常见排序操作

前言

linux 系统下的命令常常给人一种短小精悍的感觉,使用起来就像一把把锋利的小刀,在自己专注的领域做到极致,今天要聊的就是 linux 环境下的排序命令 sort,处理文本按列排序非常方便,最近使用 sort命令来排序日志查找问题,为了防止一段时间不用又会忘记,所以记录下来便于下次查找。

命令作用

sort 命令默认会将待排序内容以空格划分为多个列,然后对内容进行按列排序,命令本身不会修改待排序内容,而是将排序结果重新输出,如果想修改待排序源文件的内容,可以通过重定向命令来实现。

命令格式为:

1
sort [选项] 文件名

常见选项

sort 作为一个强大的命令,参数选项还挺多的,不过我只列举一些常见的参数,方便日常使用即可。

  • -k: 指定排序依据的列数,可以分多次指定
  • -o: 将排序后的结果存入指定文件
  • -c: 检查指定文件是否已经排好序
  • -u: 删除所有重复行
  • -b: 忽略每行或字段前面开始出的空格字符
  • -f: 排序比较时忽略大小写
  • -n: 转化为数字,按照数值的大小排序
  • -r: 反向排序,从大到小
  • -t: 指定排序时划分列数的分隔字符

数据文件

为了展示 sort 命令的作用,专门利用 ls 命令产生了一段数据,并保存在了 data.txt 文件中,之后会利用这个文件来展示 sort 的用法,文件内容展示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ cat data.txt
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority

这个文件中的内容在使用 sort 命令排序时默认以空格分割,所以共有9列,在指定列数时从1开始,接下来我们用这些数据来测试一下排序命令的用法。

核心参数

对于我来说 sort 命令的核心参数是 -k,其完整的参数列表为 -k START_F[.START_C][OPTIONS][,END_F[.END_C][OPTIONS]],参数列表很长,但是不要恐惧,逐步分析就可以了。

-k 后面这已打算都是用来指定排序依据的范围的,其中 START_FEND_F 表示开始和结束的字段,也就是列数,.START_C.END_C 表示指定字段开始和结束的字符数,OPTIONS 是由一个或多个单个字母排序的选项[bdfgiMhnRrV],这些选项中常用的已经列举在前面了,写在此处的选项会覆盖全局排序选项。

这样文字叙述有些枯燥,可以看下这个参数 -k 6.2b,6.3b,这个排序选项的含义是把内容按照第6列的第2个字符到第6列的第3个字符排序,查找字符位置的时候要去掉前面的空白。

用法展示

看了以上的参数可能还是不太清楚具体怎样用,所以举了下面这些例子,可以方便的处理常用的排序工作。

按照指定列排序

这是最普通的排序要求了,也是我用的最多的情况,需要使用-k参数

  • 按照第3列排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -k3,3 data.txt
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo

root 已经被排到了所有albert的后面

将排序结果存入指定文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
albert@home-pc:~$ sort -k3,3 data.txt -o dst.txt
albert@home-pc:~$ cat dst.txt
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo

排序结果已经被存储到了文件 dst.txt 中,其实这个命令还可以改写成 sort data.txt > dst.txt

查看文件是否已经排序好

  • 测试没排好序的文件
1
2
albert@home-pc:~$ sort -k3,3 data.txt -c
sort: data.txt:2: disorder: -rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
  • 测试已经排序的文件
1
2
albert@home-pc:~$ sort -k3,3 dst.txt -c
albert@home-pc:~$

对于已经拍好序的文件使用 -c 参数没有任何输出,如果是未排序的文件则会给出提示

去掉排序结果中的重复行

1
2
3
albert@home-pc:~$ sort -k3,3 data.txt -u
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo

这里的重复行参考是你指定排序依据的列数,也就是第3列如果重复就会认为是重复行,结果中只能出现一次

按照数值结果进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -k5n,5 data.txt
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*

这里使用了 -k5n,5 作为排序选项,其中的 n 表示以数值方式排序,如果不加 n 的排序结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -k5,5 data.txt
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*

数据看起来很乱,其实也是按照第5列排好序的,仔细分析你会发现是把这些数字当成字符串排的序

反向排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -k3,3 data.txt -r
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/

按照第3列反向排序,root就排到了所有albert的前面

自定义分割字符

sort 命令默认是以空格作为列的分割符号的,可以使用 -t 选项自定义分割符,比如我们使用 : 作为分隔符,然后以第二列进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -t ":" -k2,2 data.txt
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful

结果是以分钟数进行的排序

综合排序

学习了上面这么多参数,可以做一个综合的例子,以第6列的月份从小到大排序,以第5列文件大小逆序排列,通过组合上面的参数,可以使用下面的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
albert@home-pc:~$ sort -k6,6 -k5rn,5 data.txt
-rwxrwxr-x 1 albert albert 20328 Jul 18 19:49 mainpro*
-rwxrwxr-x 1 albert albert 9272 Jul 18 22:27 a.out*
drwx------ 1 albert albert 4096 Jul 16 00:52 .config/
drwxrwxrwx 1 albert albert 4096 Jul 16 01:10 .cache/
drwxrwxrwx 1 albert albert 4096 Jul 19 21:19 .vscode-server/
-rw-r--r-- 1 albert albert 3771 Jul 16 00:52 .bashrc
-rw------- 1 root root 2257 Jul 16 01:10 .viminfo
-rw-r--r-- 1 albert albert 655 Jul 16 00:52 .profile
-rw-r--r-- 1 albert albert 220 Jul 16 00:52 .bash_logout
-rw-rw-r-- 1 albert albert 195 Jul 18 22:27 mainpro.cpp
-rw------- 1 albert albert 35 Jul 19 14:14 .lesshst
-rw-r--r-- 1 albert albert 0 Jul 16 00:52 .sudo_as_admin_successful
-rw------- 1 albert albert 7064 Oct 17 22:14 .bash_history
-rw------- 1 albert albert 61 Sep 20 09:42 .Xauthority

总结

  • sort 命令中的 -k 选项是最重要的参数,可以指定排序依据的列数
  • sort 命令中的 -n 选项也是常用的参数,可以进行数值比较
  • 在实际问题中常常需要综合运用这些参数,参考综合例子中的方式逐步确定参数选项就可以了。

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

业精于勤,荒于嬉;行成于思,毁于随。没有人能随随便便成功~

2020-10-18 15:43:51

Albert Shi wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客