文件的排序、合并和分割

Linux的文本处理命令,包含sort、uniq、join、cut、paste、split、tr、tar,这些命令能实现对文件记录排序、统计、合并、提取、粘贴、分割、过滤、压缩和解压缩等,它们与sed和awk一起构成了Linux文本处理的所有命令和工具。

 

sort命令

# sort [选项] [输入文件]

选项 意义
-c 测试文件是否已经排序
-k 指定排序的域
-m 合并两个已排序的文件
-n 根据数字大小进行排序
-o [输出文件] 将输出写到指定的文件,相当于将输出重定向到文件
-r

将排序结果逆向显示

-t 改变域分隔符(默认是空格)
-u 去除结果中的重复行

 

先建立一个CARGO.db的示例文件:

 

Txt代码  收藏代码
  1. Thindpad:USA:14000:2009:X301  
  2. Thinkpad:HongKong:10000:2008:T400  
  3. Thinkpad:USA:8000:2007:X60  
  4. HP:China:5600:2010:DM3  
  5. HP:China:12000:2010:NE808  
  6. SumSung:Korea:5400:2009:Q308  
  7. 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 : -k 3nr,3 -k 2,2 CARGO.db  #以第3个域数字逆排序,如果第3个域相同,以第2个域再排序

# 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域数字排好序的文件合并

 

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"

 

uniq命令

选项 意义
-c 打印每行在文本中重复的次数
-d 只显示有重复的记录,每个重复记录只出现一次
-u 只显示没有重复的记录

注意uniq跟sort -u的区别,uniq的重复行必须是连在一起才会去算的,分开了就另外算一条记录了。

Bash代码  收藏代码
  1. #!/bin/bash  
  2. # 统计一个文件中每个单词出现的次数  
  3.   
  4. ARGS=1        #输入参数个数为1,就是一个文件名  
  5. E_BADARGS=55  #输入参数错误码  
  6. E_NOFILE=56   #输入文件不存在  
  7.   
  8. # 参数个数不为1,返回错误码E_BADARGS  
  9. if [ $# -ne "$ARGS" ];then  
  10.         echo "Usage: 'basename $0' filename"  
  11.         exit $E_BADARGS  
  12. fi  
  13.   
  14. # 输入的文件名不存在,返回错误码E_NOFILE  
  15. if [ ! -f "$1" ];then  
  16.         echo "File \"$1\" does not exists."  
  17.         exit $E_NOFILE  
  18. fi  
  19.   
  20. # 以下是核心算法  
  21. # sed命令用于过滤句号、逗号、分号,当然可以继续加上需要过滤的符号  
  22. # sed命令第4个-e选项将单词间的空格转化为换行符  
  23. # sort对sed过滤结果排序,每行一个单词  
  24. # uniq -c输出重复行的次数,sort -nr 按照出现频率从大到小排序  
  25. sed -e 's/[\.\,\:\;\!]/ /g' -e 's/\s\+/ /g' -e 's/\s\+$//g' -e 's/ /\n/g' "$1" | sort | uniq -c | sort -nr  
  26.   
  27. exit 0  

 

cut命令

cut命令用于从标准输入或文本文件中按域或字符提取文本

cut -c/-f/-d input

-c:指定提取的第几个字符或字符范围

-f:指定其他的第几个于或域范围

-d:改变域分隔符

# cut -c3 input.txt   -> 提取每行第三个字符

# cut -c1-5 input.txt   -> 提取每行第1至第5个字符

# cut -c1,5 input.txt   -> 提取每行第1和第5个字符

# cut -d: -f1,4 input.txt  -> 以:作为分隔符提取第1和第4个域

# cut -d: -f1-3 input.txt  -> 以:作为分隔符提取第1至第3域

 

paste命令

paste用于将文本文件或标准输出中的内容粘贴到新的文件中去,它可以将来自不同文件的数据粘贴在一起,输出到标准输出中去,或重定向到一个新的文件。

# paste [option] file1 file2

-d:默认域分隔符是空格或Tab键,设置新的域分隔符

-s:将每个文件粘贴成一行

-:从标准输入中读取数据

# paste -d@ FILE1 FILE2   -> 每一行FILE1输入在前,FILE2数据在后,然后用@分割

注:paste的-d跟其他sort、join、cut命令是不一样的,仅仅是为了设置输出文件的格式而已。

 

split命令

split命令用于将大文件切割成小文件,split命令可以按照文件的行数、字节数切割文件,并能在输出的多个小文件中自动加上编号。

# split [option] bigfile smallfile

- 或 -l:用于指定切割成的小文件的行数

-b:指定切割成的小文件的字节数

-C:与-b类似,也是指定字节数,但是切割时尽量维持每行的完整性

# split -2 big.txt small.txt

split命令切割成的小文件最多只能有1000行

# split -b100 big.txt small.txt

# split -C100 big.txt small.txt

 

--------------------------常见命令------------------------------

# 文件夹下面查找最大的文件:

# find -type f ! -path '*/.svn/*' -exec stat -c "%s %n" {} \;|sort -nr|head -10

posted @ 2014-07-23 11:41  subsir  阅读(632)  评论(0编辑  收藏  举报