Shell 行排序,对文本文件进行排序是一项常见的任务。sort
命令能够对文本文件和stdin
进行排序。它可以配合其他命令来生成所需要的输出。uniq
经常与sort
一同使用,提取不重复(或重复)的行。本章将演示sort
和uniq
命令的常见用法。
预备知识
sort
和uniq
命令可以从特定的文件或stdin
中获取输入,并将输出写入stdout
。
实战演练
(1) 可以按照下面的方式排序一组文件(例如file1.txt和file2.txt):
$ sort file1.txt file2.txt > sorted.txt
或是
$ sort file1.txt file2.txt -o sorted.txt
(2) 按照数字顺序排序:
$ sort -n file.txt
(3) 按照逆序排序:
$ sort -r file.txt
(4) 按照月份排序(依照一月、二月、三月……):
$ sort -M months.txt
(5) 合并两个已排序过的文件:
$ sort -m sorted1 sorted2
(6) 找出已排序文件中不重复的行:
$ sort file1.txt file2.txt | uniq
(7) 检查文件是否已经排序过:
#!/bin/bash
#功能描述:排序
sort -C filename ;
if [ $? -eq 0 ]; then
echo Sorted;
else
echo Unsorted;
fi
将filename
替换成你需要检查的文件名,然后运行该脚本。
工作原理
sort
命令包含大量的选项,能够对文件数据进行各种排序。如果使用uniq
命令,那sort
更是必不可少,因为前者要求输入数据必须经过排序。
sort
和uniq
可以应用于多种场景。让我们来看一下这些命令的各种选项及用法。
要检查文件是否排序过,可以利用以下事实:如果文件已经排序,sort
会返回为0的退出码($?
),否则返回非0。
if sort -c fileToCheck ; then echo sorted ; else echo unsorted ; fi
补充内容
我们已经介绍了sort
命令的基本用法。下面来看看如何利用sort
来完成一些复杂的任务。
- 依据键或列排序
如果输入数据的格式如下,我们可以按列排序:
$ cat data.txt
1 mac 2000
2 winxp 4000
3 bsd 1000
4 linux 1000
有很多方法可以对这段文本排序。目前它是按照序号(第一列)来排序的。我们也可以依据第二列和第三列来排序。
-k
指定了排序所依据的字符。如果是单个数字,则指的是列号。-r
告诉sort
命令按照逆序进行排序。例如:
# 依据第1列,以逆序形式排序
sort -nrk 1 data.txt 4 linux 1000 3 bsd 1000 2 winxp 4000 1 mac 2000 # -nr表明按照数字顺序,采用逆序形式排序 # 依据第2列进行排序 sort -k 2 data.txt
3 bsd 1000
4 linux 1000
1 mac 2000
2 winxp 4000
一定要留意用于按数字顺序进行排序的选项
-n
。sort
命令对于字母表排序和数字排序有不同的处理方式。因此,如果要采用数字顺序排序,就应该明确地给出-n
选项。
-k
后的整数指定了文本文件中的某一列。列与列之间由空格分隔。如果需要将特定范围内的一组字符(例如,第2列中的第4~5个字符)作为键,应该使用由点号分隔的两个整数来定义一个字符位置,然后将该范围内的第一个字符和最后一个字符用逗号连接起来:
$ cat data.txt
1 alpha 300
2 beta 200
3 gamma 100
$ sort -bk 2.3,2.4 data.txt ; # 按照m、p、t的顺序排序
3 gamma 100
1 alpha 300
2 beta 200
把作为排序依据的字符写成数值键。为了提取出这些字符,用其在行内的起止位置作为键的书写格式(在上面的例子中,起止位置是2和3)。
用第一个字符作为键:
$ sort -nk 1,1 data.txt
为了使sort
的输出与以