总结
ps -ef: 显示所有程序,结合sort -k排序目前 CPU 或 内存占用情况top: 更好用的监控系统资源占用情况,PCPU 排序,M内存排序sort [File...]: 默认按第一列字符ASCII排序。可以多个文件内容一块排序-r: 降序排序-k x,x: 按列排序,显性设定End在同一列,符合我们的惯性思维。-t: 指定分隔符-n: 按数字大小排序
需要留意,如果
sort -k x未指明End,排序内容为起始点到行末,排序时并没有列的概念,分隔符只服务于找到两个点,找到两个点后取出两点间的文本,分隔符被过滤掉。详细可以看文中--分隔符与排序的关系
1. 前提提要、场景
ps aux 可以显示所有的程序进程(不推荐)
a: 显示现行终端机下的所有程序,包括其他用户的程序u: 以用户为主的格式来显示程序状况x: 显示所有程序,不以终端机来区分

ps -ef 也可以显示所有的程序进程(推荐)
ps aux会截断command列,而-ef不会,所以推荐使用ps -ef替代ps aux
当系统卡顿的时候,我们需要查看系统的资源占用情况,并且排序占用内存、CPU 占用最高的程序靠前。这时候可以使用 sort 命令排序。
查询系统资源占用情况,更快捷的方式是使用
top命令,在top窗口中,PCPU 排序,M内存排序
2. sort 默认首字母排序
- 示例文件准备sh
$ cat <<EOF > sort.md A 4 C 2 B 3 D 1 EOF $ cat <<EOF > sort1.md A 14 C 13 B 12 D 11 EOF
命令:sort [File...]
默认按第一列字符 ASCII 排序
$ sort sort.md
A 4
B 3
C 2
D 1
也可以多个文件内容一块排序
$ sort sort.md sort1.md
A 14
A 4
B 12
B 3
C 13
C 2
D 1
D 11
3. sort -r 降序排序
命令:sort -r [File...]
$ cat <<EOF | sort -r sort.md
A 4
B 3
C 2
D 1
EOF
D 1
C 2
B 3
A 4
4. sort -k 按列排序
命令:sort -k Start[,End] [File...]
列的起始值是 1, 不是 0
$ cat <<EOF | sort -k 2 sort.md
A 4
B 3
C 2
D 1
EOF
D 1
C 2
B 3
A 4
5. sort -t 指定分隔符
默认分隔符为空格,但有时候文本的分隔符为其他,这时候就可以用 -t 参数
命令:sort -t [File...]
$ cat <<EOF | sort -t : -k 2
A:14
C:13
B:12
D:11
EOF
D:11
B:12
C:13
A:14
6. 排序细节
6.1 ASCII 码排序
默认根据字符排序,即 ASCII 码排序,如果同一位置具有相同的字符,则继续比对后一位置的 ASCII 码,直到行末。
$ cat <<EOF | sort
130
121
120
14
13
1
EOF
# 从第一个字符的 ASCII 码开始对比,相同则对比下一位,以此类推
1
120
121
13
130
14
如果想根据数字大小排序,可以使用后续介绍的 -n 参数
6.2 分隔符与排序的关系
$ cat <<EOF | sort -k 1
15
1
EOF
# 这个结果大家应该没有疑问
1
15
$ cat <<EOF | sort -k 1
15 6
1 6
EOF
# 这个结果就有点出乎意料了
# 不应该 1 小于 15,排前面吗
15 6
1 6
要解答这个疑问,先看看 之前在介绍 -k ,写的这个简单的命令描述sort -k Start[,End] [File...]
实际上完整的命令描述为:sort -k F[.C][OPTS][,F[.C][OPTS]] [File...]
F: 字段序号(field number),即第几列,默认StartF为第 1 列,EndF为最后一列c: 在字段中的第几个字符开始对比,默认StartC在开始字段的第一个字符,截止EndC为行末。[OPTS]: 排序方法[bdfgiMhnRrV],在Start或End中指定都是等效的。未指定则继承全局
可以理解为 sort -k 只关注两个点之间的内容,毕竟 F 和 c 的描述的是点的位置(第几列第几个字符)。而分隔符直接过滤掉。
# 现在再回过头来看这道题
$ cat <<EOF | sort -k 1
15 6
1 6
EOF
# 这里没有指定前后两个点,所以默认是行头行尾
# 内容为本行全部,再过滤掉分隔符,剩余内容为
156
16
# 根据字符 ASCII 排序,逐字对比排序后,排序如下
156
16
# 补上分隔符
15 6
1 6
两个点之间的文本,那如果将两个点约束同个列上,例如第 1 列,能否实现我们期待的效果
$ cat <<EOF | sort -k 1,1
15 6
1 6
EOF
1 6
15 6
确实可以,这就符合我们的惯性思维了,所以尽量使用 sort -k x,x,指定好 End 在同一列。
继续验证
# 之前的数据是
# 15 6
# 1 6
# 如果把第二行数据的 1 6 改成 1 4
# 去掉分隔符,14 比 15 小,要排前面
# 尝试一下
$ cat <<EOF | sort -k 1
15 6
1 4
EOF
# 和预想一致
1 4
15 6
那么不同分隔符对排序有影响吗?
空格的 ASCII 为 32,比数字小。我尝试过比数字大值为 124 的 |,结论是没影响,就不补充 demo 了,有兴趣可以自己试试。
但网上有一些结论是:分隔符作为了文本参与了排序。这个结论我不认同,因为无法解释,为什么换了分隔符排序结果不受影响。
所以我还是保持观点: 分隔符在排序时直接被过滤掉
15 6
1 6
总结一下: 一开始会认为1 6要排在15 6前面,是主观的认为这里是两个列,对比完第一个列后,再对比第二个列。
但实际上,-k只会记录前后两个点,由这两个点去获取中间的文本。分隔符可以分隔列,但最终目的,只是服务于找到点的位置。随后取出中间文本后便把分割符过滤了。
使用sort -k x,x显性设定End在同一列,符合我们的惯性思维。
还有其他小的细节,可以参考 linux sort 命令整理
7. sort -n 按数字大小排序
命令:sort -n [File...]
$ sort -nk 2 sort.md sort1.md
D 1
C 2
B 3
A 4
D 11
B 12
C 13
A 14
8. 字符串排序
前面都是以行为单位排序,也可以配合其他命令,实现以字符为单位的排序
本质是利用 grep -o 将字符串转为行,sort 排序后,tr -d 删除换行符还原为字符串。
# grep -o:--only-matching,仅仅打印匹配到的字符,相当于将 hello 分成每行一个字符
# tr -d '\n':删除所有换行符
$ echo hello | grep -o . | sort | tr -d '\n'
ehllo