基础知识回顾:Sort 和 Uniq
学习在命令行中排序和去重文本的基本原理。
如果您长期使用命令行,很容易对您每天使用的命令习以为常。但是,如果您是 Linux 命令行的新手,有一些命令可以使您的生活更轻松,但您可能不会自动发现它们。在本文中,我将介绍任何人武器库中都必不可少的两个命令的基础知识:sort
和 uniq
。
sort
命令的功能正如其名:它接受文本数据作为输入,并输出排序后的数据。在命令行中,有很多情况下您可能需要对输出进行排序,例如来自不提供自身排序选项的命令的输出(或者排序参数足够晦涩,以至于您直接使用 sort
命令)。在其他情况下,您可能有一个包含大量数据(可能是由其他脚本生成)的文本文件,并且您需要一种快速的方式以排序形式查看它。
让我们从一个名为 "test" 的文件开始,其中包含三行
Foo
Bar
Baz
sort
可以通过 STDIN 重定向、管道输入或文件输入进行操作,在文件的情况下,您也可以直接在命令中指定文件。因此,以下三个命令都完成相同的操作
cat test | sort
sort < test
sort test
您从所有这些命令中获得的输出是
Bar
Baz
Foo
数值输出排序
现在,让我们通过添加另外三行来使文件复杂化
Foo
Bar
Baz
1. ZZZ
2. YYY
11. XXX
如果您再次运行上述 sort
命令之一,这次,您将看到不同的输出
11. XXX
1. ZZZ
2. YYY
Bar
Baz
Foo
这可能不是您想要的输出,但它指出了关于 sort
的一个重要事实。默认情况下,它是按字母顺序排序,而不是按数字顺序排序。这意味着以 "11." 开头的行排在以 "1." 开头的行之上,并且所有以数字开头的行都排在以字母开头的行之上。
要按数字排序,请将 -n
选项传递给 sort
sort -n test
Bar
Baz
Foo
1. ZZZ
2. YYY
11. XXX
查找文件系统上最大的目录
数值排序在许多命令行输出中都非常有用——特别是当您的命令包含某种计数,并且您想查看计数中最大或最小的项时。例如,如果您想找出哪些文件在特定目录中占用了最多的空间,并且您想递归地深入挖掘,您将运行类似这样的命令
du -ckx
此命令递归地深入到当前目录,并且不遍历该目录内的任何其他挂载点。它统计文件大小,然后按照找到它们的顺序输出每个目录,并在其前面加上该目录下方文件的大小(以千字节为单位)。当然,如果您正在运行这样的命令,很可能是因为您想知道哪个目录占用的空间最多,而这就是 sort
的用武之地
du -ckx | sort -n
现在您将获得当前目录下所有目录的列表,但这次是按文件大小排序的。如果您想更进一步,可以将它的输出通过管道传递给 tail
命令以查看前十个。另一方面,如果您希望最大的目录位于输出的顶部,而不是底部,您将添加 -r
选项,该选项告诉 sort
反转顺序。因此,要获得前十个(实际上是前八个——第一行是总计,下一行是当前目录的大小)
du -ckx | sort -rn | head
这可以工作,但通常使用 du
命令的人希望看到比千字节更易读的输出大小。du
命令提供了 -h
参数,该参数提供“人类可读”的输出。因此,您将看到像 9.6G
而不是使用 -k
选项的 10024764
这样的输出。但是,当您将该人类可读的输出通过管道传递给 sort
时,您将不会获得默认情况下期望的结果,因为它会将 9.6G 排在 9.6K 之上,而 9.6K 又会排在 9.6M 之上。
sort
命令本身有一个 -h
选项,它的作用类似于 -n
,但它能够解析标准的人类可读数字并相应地对其进行排序。因此,要查看当前目录中最大的十个目录,并使用人类可读的输出,您将键入此命令
du -chx | sort -rh | head
移除重复项
sort 命令不限于排序一个文件。您可以将多个文件通过管道传递给它,或者在命令行中列出多个文件作为参数,它会将它们全部组合并排序。但不幸的是,如果这些文件包含一些相同的信息,您最终会在排序后的输出中得到重复项。
要删除重复项,您需要 uniq
命令,该命令默认情况下从其输入中删除任何彼此相邻的重复行,并输出结果。因此,假设您有两个文件,它们是不同的名称列表
cat namelist1.txt
Jones, Bob
Smith, Mary
Babbage, Walter
cat namelist2.txt
Jones, Bob
Jones, Shawn
Smith, Cathy
您可以通过管道传递到 uniq
来删除重复项
sort namelist1.txt namelist2.txt | uniq
Babbage, Walter
Jones, Bob
Jones, Shawn
Smith, Cathy
Smith, Mary
uniq
命令的功能远不止于此。它还可以仅输出重复的行,因此您可以通过添加 -d
选项快速找到一组文件中的重复项
sort namelist1.txt namelist2.txt | uniq -d
Jones, Bob
您甚至可以让 uniq
提供一个计数,统计它使用 -c
选项找到每个条目的次数
sort namelist1.txt namelist2.txt | uniq -c
1 Babbage, Walter
2 Jones, Bob
1 Jones, Shawn
1 Smith, Cathy
1 Smith, Mary
正如您所看到的,“Jones, Bob” 出现的次数最多,但是如果您有很多行,这种计数可能对您来说不太有用,因为您希望最多的重复项浮到顶部。幸运的是,您有 sort
命令
sort namelist1.txt namelist2.txt | uniq -c | sort -nr
2 Jones, Bob
1 Smith, Mary
1 Smith, Cathy
1 Jones, Shawn
1 Babbage, Walter
结论
我希望这些使用 sort
和 uniq
的实际示例向您展示了这些简单的命令行工具是多么强大。这些基础命令行工具的一半秘密在于发现(并记住)它们的存在,以便在您下次遇到它们可以解决的问题时,它们可以为您所用。