文本处理工具之sort,uniq详解
sort:将输入行按照键值字段与数据类型选项以及locate排序
语法: sort [option] [file(s)]
主要选项:
-b 忽略开头的空白
-c 检查文件是否已经正确排序
-f 排序时忽略大小写,均视为大写字母
-m 将几个排序好的文件,合并为一个排序后的输出数据流
-M 将前面3个字母依照月份的缩写进行排序
-k 定义排序键值字段,按照那个字段(file)进行排序
-n 依照数值的大小排序
-o outfile 将排序后的结果存入指定的文件
-r 以相反的顺序来排序,由大到小
-t chat 使用单个字符chat作为默认的字段分隔字符,取代默认的空白字符
-u 只有唯一的记录,丢弃所有具相同键值的记录,相同的数据出现一次。
--help 显示帮助。
--version 显示版本信息
1).以字段排序
排序键值字段类型
字母 | 说明 |
b | 忽略开头的空白 |
d | 字典顺序 |
f | 不区分字母大小写 |
g | 以一般的浮点数字进行比较,只适用于GNU版本 |
i | 忽略无法打印的字符 |
n | 以整数(数字)比较 |
r | 倒置排序的顺序 |
实例1:以传统ASCII码顺序排序
[gz_fieldyang@test ~]$ LC_ALL=C sort /etc/passwd
#gzdev1:x:829:829::/home/gzdev1:/bin/bash
#gzdev2:x:830:830::/home/gzdev2:/bin/bash
...
Meat:x:814:814::/home/Meat:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
...
bin:x:1:1:bin:/bin:/sbin/nologin
cvsroot:x:778:502::/home/cvsroot:/bin/bash
...
dbus:x:81:81:System message bus:/:/sbin/nologin
dovecot:x:99:99:dovecot:/usr/libexec/dovecot:/sbin/nologin
...
ftpuser:x:505:505::/home/ftpuser:/bin/bash
gdm:x:42:42::/var/gdm:/sbin/nologin
附:
# LC_ALL=C 是为了去除所有本地化的设置,让命令能正确执行。
# LC_ALL :它是一个宏,如果该值设置了,则该值会覆盖所有LC_*的设置值。注意,LANG的值不受该宏影响。
# “C”是系统默认的locale,"POSIX"是"C"的别名。所以当我们新安装完一个系统时,默认的locale就是C或POSIX。
实例2:以用户名称排序
[gz_fieldyang@test ~]$ sort -t: -k1,1 /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi:x:70:70:Avahi daemon:/:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
cvsroot:x:778:502::/home/cvsroot:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
gdm:x:42:42::/var/gdm:/sbin/nologin
...
# -t指定分隔符为分号,-K指定以第一个字段第一个字符进行排序
实例3:反向UID排序
[gz_fieldyang@test ~]$ sort -t: -k3nr /etc/passwd
[gz_fieldyang@ test ~]$ sort -t: -k3nr,3 /etc/passwd
# 更精确的字段规格应为-k3,3nr 或-k3nr,3 或-k3,3 -n -r,
# 表示从字段3起始处开始,以数值类型反向排序,并结束与字段3的结尾
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
sninf_kenchoi:x:860:860::/home/sninf_kenchoi:/bin/bash
gz_fieldyang:x:859:859::/home/gz_fieldyang:/bin/bash
gz_kinma:x:857:857::/home/gz_kinma:/bin/bash
sninf_tonyhung:x:856:856::/home/sninf_tonyhung:/bin/bash
sninf_simonlau:x:855:855::/home/sninf_simonlau:/bin/bash
sninf_kenchan:x:854:854::/home/sninf_kenchan:/bin/bash
sninf_thomaschan:x:853:853::/home/sninf_thomaschan:/bin/bash
gz_jones:x:851:851::/home/gz_jonesyan:/bin/bash
...
# -t指定分隔符为分号,-K指定以第3个字段进行排序,n表示以整数比较,r表示逆序
实例4:以唯一的GID排序
[gz_fieldyang@test ~]$ sort -t: -k4n -u /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
...
# -t指定分隔符为分号,-K指定以第4个字段进行排序,n表示以整数比较,u表示唯一排序
2).文本块排序
[gz_fieldyang@test ~]$ cat > my-friends
#SORTKEY: ma,Kin
Kin ma
zhujiangxincheng 78
D-305 Letaijie
TaiShan
#SORTKEY:yan,Jones
Jones yan
Dongpu 68
B_602 Dongpujie
YangJiang
#SORTKEY:wu,Will
Will wu
Shangshe 36
A_205 Heguanlu
MaoMing
[gz_fieldyang@test ~]$ cat my-friends |
awk -v RS="" '{ gsub("\n", "^Z"); print }' |
sort -f
#SORTKEY: ma,Kin ^ZKin ma^Zzhujiangxincheng 78 ^ZD-305 Letaijie ^ZTaiShan
#SORTKEY:wu,Will^ZWill wu^ZShangshe 36^ZA_205 Heguanlu^ZMaoMing
#SORTKEY:yan,Jones ^ZJones yan^ZDongpu 68^ZB_602 Dongpujie ^ZYangJiang
[gz_fieldyang@ test ~]$ cat my-friends | #在地址数据文件里的管道
awk -v RS="" '{ gsub("\n", "^Z"); print }' | #转换地址为单个行
sort -f | #排序地址数据,忽略大小写
awk -v ORS="\n" '{ gsub("^Z", "\n"); print }'
#恢复行结构,注意:部分版本无法恢复
#gsub()功能为全局性替换,类似于sed下的s/x/y/g架构
#SORTKEY: ma,Kin
Kin ma
zhujiangxincheng 78
D-305 Letaijie
TaiShan
#SORTKEY:wu,Will
Will wu
Shangshe 36
A_205 Heguanlu
MaoMing
#SORTKEY:yan,Jones
Jones yan
Dongpu 68
B_602 Dongpujie
YangJiang
[gz_fieldyang@ test ~]$ cat my-friends |
awk -v RS="" '{ gsub("\n", "^Z"); print }' |
sort -f |
awk -v ORS="\n" '{ gsub("^Z", "\n"); print }' |
grep -v '# SORTKRY' #删除标记行
3).sort的稳定性:不稳定
[gz_fieldyang@ test ~]$ sort -t_ -k1,1 -k2,2 << EOF
> one_two
> one_two_three
> one_two_four
> one_two_five
> EOF
one_two
one_two_five
one_two_four
one_two_three
4).删除重复
uniq :过滤数据
选项 :
-c 显示重复次数
-d 仅显示重复行
-u 仅显示未重复行
用法:
sort ... | uniq ...
实例:
[gz_fieldyang@ test ~]$ cat > number
one
two
threefour
four
five
two
one
one
[gz_fieldyang@ test ~]$ sort number | uniq #排序
five
four
one
threefour
two
[gz_fieldyang@ test ~]$ sort number | uniq -c #顺带显示重复次数
1 five
2 one
1 threefour
2 two
[gz_fieldyang@test ~]$ sort number | uniq -d #仅显示重复行
one
two
[gz_fieldyang@test ~]$ sort number | uniq -u #仅显示未重复行
five
threefour
[gz_fieldyang@test ~]$