Linux的文本处理命令,包含sort、uniq、join、cut、paste、split、tr、tar,这些命令能实现对文件记录排序、统计、合并、提取、粘贴、分割、过滤、压缩和解压缩等,它们与sed和awk一起构成了Linux文本处理的所有命令和工具。
?
5.1 sort命令
# sort [选项] [输入文件]
选项 | 意义 |
-c | 测试文件是否已经排序 |
-k | 指定排序的域 |
-m | 合并两个已排序的文件 |
-n | 根据数字大小进行排序 |
-o [输出文件] | 将输出写到指定的文件,相当于将输出重定向到文件 |
-r |
将排序结果逆向显示 |
-t | 改变域分隔符(默认是空格) |
-u | 去除结果中的重复行 |
?
先建立一个CARGO.db的示例文件:
?
Thindpad:USA:14000:2009:X301 Thinkpad:HongKong:10000:2008:T400 Thinkpad:USA:8000:2007:X60 HP:China:5600:2010:DM3 HP:China:12000:2010:NE808 SumSung:Korea:5400:2009:Q308 IdeaPad:China:8000:2007:U450
# sort -t: CARGO.db ? #以默认方式对CARGO.db进行排序,注意-t跟:之间没有空格,也可以加空格
?
# sort -t : -k3 CARGO.db
注:-k3虽然是以第三个域来排序,但还是以默认的字符排序方法,不是数字,如果第三个域相同,那么再依次以第4个域、第5个域排序。
# sort -t : -k3n CARGO.db ?#以第3个域并且以数字顺序排序
# sort -t : -k3nr CARGO.db ?#以第3个域并且以数字顺序排序,逆向排序
# sort -t : -k3nr -o out CARGO.db ?#不输出到标准输出中,而是重定向到out文件中去
#?sort -t : -k3n -c CARGO.db ?#测试一下第3个域是否已经安装数字排好了序
# sort -t: -k3n -m CARGO.db CARGO.db2 ?#将两个已经按照第3域数字排好序的文件合并
?
5.1.2 sort和awk的联合使用
文本块的排序,一个文件中有很多相似的段落,每个段落记录一个人的姓名地址等,如果段落排序:
# cat PROFESSOR.db | awk -v RS="" '{gsub("\n","@");print}' | sort | awk -v ORS="\n\n" '{gsub("@","\n");print}'
?注:awk -v 用于定义一个变量供后面使用,可以覆盖系统变量
可以看出当RS为空时,awk会自动以多行来做为分割符。 上面的RS也可以为RS="\n\n"
?
5.2 uniq命令
选项 | 意义 |
-c | 打印每行在文本中重复的次数 |
-d | 只显示有重复的记录,每个重复记录只出现一次 |
-u | 只显示没有重复的记录 |
注意uniq跟sort -u的区别,uniq的重复行必须是连在一起才会去算的,分开了就另外算一条记录了。
#!/bin/bash # 统计一个文件中每个单词出现的次数 ARGS=1 #输入参数个数为1,就是一个文件名 E_BADARGS=55 #输入参数错误码 E_NOFILE=56 #输入文件不存在 # 参数个数不为1,返回错误码E_BADARGS if [ $# -ne "$ARGS" ];then echo "Usage: 'basename $0' filename" exit $E_BADARGS fi # 输入的文件名不存在,返回错误码E_NOFILE if [ ! -f "$1" ];then echo "File \"$1\" does not exists." exit $E_NOFILE fi # 以下是核心算法 # sed命令用于过滤句号、逗号、分号,当然可以继续加上需要过滤的符号 # sed命令第4个-e选项将单词间的空格转化为换行符 # sort对sed过滤结果排序,每行一个单词 # uniq -c输出重复行的次数,sort -nr 按照出现频率从大到小排序 sed -e 's/[\.\,\:\;\!]/ /g' -e 's/\s\+/ /g' -e 's/\s\+$//g' -e 's/ /\n/g' "$1" | sort | uniq -c | sort -nr exit 0
?