前言
这篇文章主要介绍Linux Bash Shell 中的sort和uniq命令。
sort命令可以对文本文件进行排序,经常和其他命令通过管道的方式结合使用。
而uniq 命令要求输入必须是排好序的数据,否则结果就不会准确,有序是uniq命令得到正确结果的基础。
接下来让我们一起来学习sort和uniq命令吧~
sort 命令的用法
- sort 可以接多个输入
sort file1.txt file2.txt > sorted.txt
- 按照数字顺序正序排序(这里的顺序如果不特别指出,都指正序)
sort -n file.txt
- 以逆序的方式排序
sort -r file.txt
- 按照月份排序(按照Jan,Feb,March…这样的顺序)
sort -M months.txt
- 合并两个已经排好序的文件
sort -m sorted1.txt sorted2.txt
- 从一个有序的文件中找出唯一的行
sort file1.txt file2.txt | uniq
sort命令具体的例子
假设现在我们有个文件,其内容如下:
cat tmp_dir/data.txt
假设现在我们有个文件,其内容如下:: command not found
1 mac 2000
2 winxp 4000
3 bsd 1000
4 linux 1000
- 可以看到当前这个文件是按照第一列正序排序的,我们可以根据第一列逆序排序
sort -nrk 1 tmp_dir/data.txt
4 linux 1000
3 bsd 1000
2 winxp 4000
1 mac 2000
-k
指定依据哪列进行排序。比如我们可以指定依照第二列进行排序,从输出结果来看,我们可以看出不指定-n时,默认时按照字母序进行排序。
sort -k 2 tmp_dir/data.txt
3 bsd 1000
4 linux 1000
1 mac 2000
2 winxp 4000
为什么不指定-n
? 因为第二列不是数字,所以无法指定-n
选项。 那么如果非要指定会出现什么结果呢?
sort -nk 2 tmp_dir/data.txt # 错误示例,对非数字列指定了-n 选项
1 mac 2000
2 winxp 4000
3 bsd 1000
4 linux 1000
从结果可以看出,对非数字列指定-n
后,无法正确排序。 所以记得不要对非数字列指定-n
选项,因为-n
是指按照数字序进行排序,而默认时按照字母序进行排序。
-z
选项,指定sort的输出以’\0′ 结束,读过之前文章的朋友应有印象,有时我们不知道某些文本的结束符时什么,因此需要指定输出格式为’\0’,以避免触发不必要的操作
sort -z tmp_dir/data.txt | xargs -0
1 mac 2000
2 winxp 4000
3 bsd 1000
4 linux 1000
-m
合并两个已经排好序的文件
现有两个有序文件sorted1.txt 和sorted2.txt
cat tmp_dir/sorted1.txt
1
3
4
6
cat tmp_dir/sorted2.txt
2
4
5
9
利用 -m
参数实现合并功能。
sort -m tmp_dir/sorted1.txt tmp_dir/sorted2.txt
1
2
3
4
4
5
6
9
-M
选项按照月份排序,这个功能比较陌生,但是挺有意思我们来一起看下。现有一个month.txt文件,其内容如下:
cat tmp_dir/month.txt
Feb
March
Jan
June
May
如果我们按照字母序排序,会得到下面的输出:
sort tmp_dir/month.txt
Feb
Jan
June
March
May
但是如果我们指定了 -M
选项,它就会按照月份的时间顺序进行排序,结果如下:
sort -M tmp_dir/month.txt
Jan
Feb
March
May
June
可以看出,排序后的结果是具有月份的先后顺序意义的。
uniq 命令
uniq
命令通过过滤掉重复的行,来实现输出唯一的行数据的功能。uniq
命令只能用于排好序的数据,因此经常和sort
命令一起使用。
uniq命令的用法
- 过滤重复行数据,即如果有重复行数据只输出一行
uniq sorted.txt
- 仅仅显示不重复的行数据
uniq -u sorted.txt
- 只显示重复的数据
uniq -d sorted.txt
- 统计每一行数据出现的次数
uniq -c sorted.txt
uniq命令的具体用法
现有一个排好序的文本文件,其内容如下:
cat tmp_dir/text_sorted.txt
bash
foss
hack
hack
- 过滤重复数据,重复数据只保留一行。 从输出可以看到只显示了一行hack, 重复的被过滤掉了.
uniq tmp_dir/text_sorted.txt
bash
foss
hack
- 仅仅显示不重复的数据, 从输出结果看重复的两条hack数据,一条也没有显示
uniq -u tmp_dir/text_sorted.txt
bash
foss
- 统计每一行出现的次数
uniq -c tmp_dir/text_sorted.txt
1 bash
1 foss
2 hack
- 只显示重复的数据
uniq -d tmp_dir/text_sorted.txt
hack
-s
和-w
两个高级用法,-s
指定比较数据时,跳过前N个字符。-w
指定比较数据时做多只比较几个字符。
有个这样的数据
cat tmp_dir/text_data.txt
u:01:gnu
d:04:linux
u:01:bash
u:01:hack
sort tmp_dir/text_data.txt | uniq -s 2 -w 2
d:04:linux
u:01:bash
从结果可以看出,指定-s 2
,会以01这列作为比较的依据,虽然01:bash 和01:hack等式不重复的行,但是因为指定了-w 2
即只比较两个字符并不比较整行数据。
作为对比,我们可以看下不指定-w
选项后的结果
sort tmp_dir/text_data.txt | uniq -s 2
d:04:linux
u:01:bash
u:01:gnu
u:01:hack
可以看到,去掉了-w 2
后,会以01开始后的所有数据作为比较的依据。
Be First to Comment