首页 > 代码库 > 第五章 shell学习之文件的排序、合并和分割

第五章 shell学习之文件的排序、合并和分割

sort命令

sort [选项] [输入文件]

选项:

-c 测试文件是否已经排序,如果未被排序则输出第一个未被排序的记录

-k 指定排序的域

-m 合并两个已排序的文件,合并的文件也已经排序,如sort -m a1 a2,a1的记录被有序的插入a2

-n 根据数字的大小进行排序,一般放在域号后,如-k3n

-o 将输出重定向到指定文件

-r 将排序结果逆向显示

-t 改变域分割符,如-t:

-u 去除结果中的重复行

sort和awk联合

例:

[root@localhost tmp]# cat test1.txt 

B liu

dfad

dfw,sfa

A clc

wers

sdfa,werw

F kkk

ckaf

fdwae,fwefs

E ccc

werw

sfdf,cdfae

[root@localhost tmp]# cat test1.txt | awk -v RS="\n\n" ‘{gsub("\n","@");print $0}‘ | sort | awk ‘BEGIN {ORS="\n\n"} {gsub("@","\n");print $0}‘

A clc

wers

sdfa,werw

B liu

dfad

dfw,sfa

E ccc

werw

sfdf,cdfae

F kkk

ckaf

fdwae,fwefs

uniq命令

去除文本中连续重复的行,不连续重复的行不能去除(这是和sort -u的区别)

选项:

-c 打印每行在文本总重复出现的次数

-d 只显示重复的记录,每个重复的记录只显示一次

-u 只显示没有重复的记录

例:统计字数

[root@localhost tmp]# cat test2.txt 

thank you all the same,but no thank you,you are same with him.

did you right.

[root@localhost tmp]# cat a4.sh 

#! /bin/sh

argc=1

e_badarg=55

e_nofile=56

if [ $# -ne $argc ]   #参数个数错误

then

echo "arg error"

exit $e_badarg

fi

if [ ! -f $1 ]   #文件未找到

then

echo "file no found"

exit $e_nofile

fi

sed -e ‘s/\./ /g‘ -e ‘s/\,/ /g‘ -e ‘s/ /\n/g‘ "$1" | sed ‘/^$/d‘ | sort | uniq -c | sort -rn

exit 0

[root@localhost tmp]# ./a4.sh test2.txt 

      4 you

      2 thank

      2 same

      1 with

      1 the

      1 right

      1 no

      1 him

      1 did

      1 but

      1 are

      1 all

join命令

实现两个文件记录的连接操作,即将两个文件中具有相同域的记录选出来,把这两个记录的所有域放到同一行

注意join只能对按照两个按照相同域排序的文件进行连接

选项:

-a1或-a2 除了显示共同域,-a1或-a2分别显示第一或第二个文件中没有的共同域的记录

-i 比较域的内容时忽略大小写

-o 设置结果显示的格式

-t 改变域分隔符

-v1或-v2 分别显示第一或第二个文件中没有的共同域的记录,但不显示共同域连接结果

-1和-2 分别设置文件1和文件2用于连接的域

例:

1.

[root@localhost tmp]# cat test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

[root@localhost tmp]# cat test4.txt 

clc1:aaa:A

clc2:bbb:B

clc3:ccc:C

clc5:eee:E

[root@localhost tmp]# join -t: test3.txt test4.txt 

clc1:111:A:aaa:A

clc2:222:B:bbb:B

clc5:555:E:eee:E

默认只显示两个文件有共同域的连接结果

2.

[root@localhost tmp]# join -t: -a1 test3.txt test4.txt 

clc1:111:A:aaa:A

clc2:222:B:bbb:B

clc4:444:D

clc5:555:E:eee:E

[root@localhost tmp]# join -t: -v1 test3.txt test4.txt 

clc4:444:D

clc4:222:D为test3.txt特有

3.

[root@localhost tmp]# join -t: -1 3 -2 3 test3.txt test4.txt 

A:clc1:111:clc1:aaa

B:clc2:222:clc2:bbb

E:clc5:555:clc5:eee

以第一个文件的第3个域和第二个文件的第3个域作为连接的域,默认都为第一个域,注意连接的域放在了第一位

4.

[root@localhost tmp]# join -t: -1 3 -2 3 -o 1.1 1.3 2.2 1.2 test3.txt test4.txt

clc1:A:aaa:111

clc2:B:bbb:222

clc5:E:eee:555

调整显示的位置,1.1为先显示文件1的第一个域

cut命令

从标准输入或文本文件中按字符或者域提取文本

选项:

-c 按字符提取

-f 按域提取

-d 定义域分隔符,相当于sort和join的-t

例:

[root@localhost tmp]# cat test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

[root@localhost tmp]# cut -c1,4 test3.txt 

c1

c2

c4

c5

[root@localhost tmp]# cut -d: -f2-3 test3.txt 

111:A

222:B

444:D

555:E

paste命令

将文本文件或者标准输出的数据粘贴到一起

paste [选项] 文件1 文件2

选项:

-d 设置输出的域分隔符,默认为tab

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

格式:文件1的记录1分隔符文件1的记录2...  换行 文件2的记录1分隔符文件2的记录2...

而默认格式:文件1的记录1分隔符文件2的记录1 换行 文件1的记录2分隔符文件2的记录2

- 从标准输入中读取数据

例:

[root@localhost tmp]# cat test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

clc6:666:F

[root@localhost tmp]# cat test4.txt 

clc1:aaa:A

clc2:bbb:B

clc3:ccc:C

clc5:eee:E

[root@localhost tmp]# paste test3.txt test4.txt 

clc1:111:A      clc1:aaa:A

clc2:222:B      clc2:bbb:B

clc4:444:D      clc3:ccc:C

clc5:555:E      clc5:eee:E

clc6:666:F

[root@localhost tmp]# paste -s test3.txt test4.txt 

clc1:111:A      clc2:222:B      clc4:444:D      clc5:555:E      clc6:666:F

clc1:aaa:A      clc2:bbb:B      clc3:ccc:C      clc5:eee:E

[root@localhost tmp]# paste -d@ test3.txt test4.txt 

clc1:111:A@clc1:aaa:A

clc2:222:B@clc2:bbb:B

clc4:444:D@clc3:ccc:C

clc5:555:E@clc5:eee:E

clc6:666:F@

[root@localhost tmp]# paste -s -d@ test3.txt test4.txt 

clc1:111:A@clc2:222:B@clc4:444:D@clc5:555:E@clc6:666:F

clc1:aaa:A@clc2:bbb:B@clc3:ccc:C@clc5:eee:E

[root@localhost tmp]# ls | paste -d: - - - -      #以:为分隔符每行显示4个文件

1c:a:a1:a1~

a1.awk:a2.awk:a3.awk:a4.awk

a4.sh:aa:aabc:aac

a.awk:a.sh:b:b1

split命令

把大文件切割存放在多个小文件中

split [选项] 待切割的大文件 输出的小文件

选项:

-或-l 两个等价,指定大文件几行被切一次

-b 指定大文件多少字节被切一次

-C 与-b类似,但是尽量维持每行的完整性

例:

1.按行分割文件

[root@localhost tmp]# cat test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

clc6:666:F

[root@localhost tmp]# split -2 test3.txt clc.txt

[root@localhost tmp]# ls clc*

clc.txtaa  clc.txtab  clc.txtac

[root@localhost tmp]# cat clc.txtaa

clc1:111:A

clc2:222:B

[root@localhost tmp]# cat clc.txtab

clc4:444:D

clc5:555:E

[root@localhost tmp]# cat clc.txtac

clc6:666:F

2.按字节分割文件

[root@localhost tmp]# ll test3.txt 

-rw-r--r-- 1 root root 55 Dec 15 18:20 test3.txt

[root@localhost tmp]# split -b 20 test3.txt clc.db

[root@localhost tmp]# ll clc.db*

-rw-r--r-- 1 root root 20 Dec 15 18:44 clc.dbaa

-rw-r--r-- 1 root root 20 Dec 15 18:44 clc.dbab

-rw-r--r-- 1 root root 15 Dec 15 18:44 clc.dbac

[root@localhost tmp]# cat clc.dbaa

clc1:111:A

clc2:222:[root@localhost tmp]# cat clc.dbab

B

clc4:444:D

clc5:55[root@localhost tmp]# cat clc.dbac

5:E

clc6:666:F

3.按字节分割文件但是尽量保留行的完整性

[root@localhost tmp]# split -C 20 test3.txt clc.db

[root@localhost tmp]# ll clc.db*

-rw-r--r-- 1 root root 11 Dec 15 18:46 clc.dbaa

-rw-r--r-- 1 root root 11 Dec 15 18:46 clc.dbab

-rw-r--r-- 1 root root 11 Dec 15 18:46 clc.dbac

-rw-r--r-- 1 root root 11 Dec 15 18:46 clc.dbad

-rw-r--r-- 1 root root 11 Dec 15 18:46 clc.dbae

[root@localhost tmp]# cat clc.dbaa

clc1:111:A

...

tr命令

实现字符转换功能,可用sed代替

只能标准输入,即要么将文件重定向到标准输入,要么用管道

tr [选项] 字符串1 字符串2 <输入文件

选项:

-c 反选字符串1

-d 删除标准输入在字符串1中出现的所有字符

-s 删除标准输入在字符串1中出现的重复字符,只保留1个

例:

[root@localhost tmp]# cat test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

clc6:666:F

1.删除0-9

[root@localhost tmp]# tr -d 0-9 < test3.txt 

clc::A

clc::B

clc::D

clc::E

clc::F

2.去除标准输入(test3.txt)中重复的数字,保留1个

[root@localhost tmp]# tr -s 0-9 < test3.txt 

clc1:1:A

clc2:2:B

clc4:4:D

clc5:5:E

clc6:6:F

3.去除除了数字以外的重复字符,保留一个(这个例子中去除了/n)

[root@localhost tmp]# tr -sc 0-9 < test3.txt 

clc1:111:A

clc2:222:B

clc4:444:D

clc5:555:E

clc6:666:F

tar命令

压缩和解压缩

压缩包有两种,tar格式和gzip格式,gzip格式相当于在tar格式上再进行进一步压缩

tar [选项] 文件或目录

选项:

-c 创建新的包

-r 为包添加新的文件

-t 列出包内容

-u 更新包中的文件,如无此文件则添加,课代替-r

-x 解压缩文件

-f 使用压缩文件或设备,必选

-v 显示tar处理文件的信息

-z 用gzip压缩和解压缩文件,若创建压缩包(-c)加上-z则解压(-x)也要加上-z,实质上为先tar -cf变为tar再gzip变为gzip

不能直接往gzip格式的包中添加(-r或-u)文件,要先变为tar格式(gzip -d),添加(tar -rf)完后在进一步压缩成gzip格式(gzip)

例:

[root@localhost tmp]# ls clc* test*.txt

clc.dbaa  clc.dbac  clc.dbae   test2.txt  test4.txt

clc.dbab  clc.dbad  test1.txt  test3.txt

[root@localhost tmp]# tar -zcf all.tar.gz clc*      #创建压缩文件,直接压缩成gzip格式

[root@localhost tmp]# tar -tf all.tar.gz         #查看压缩包内容

clc.dbaa

clc.dbab

clc.dbac

clc.dbad

clc.dbae

[root@localhost tmp]# gzip -d all.tar.gz    #把gzip压缩包解压成tar压缩包

[root@localhost tmp]# ls all*

all.tar

[root@localhost tmp]# tar -rf all.tar test*.txt    #往tar压缩包添加文件,注意不能往gzip直接添加文件

[root@localhost tmp]# tar -tf all.tar 

clc.dbaa

clc.dbab

clc.dbac

clc.dbad

clc.dbae

test1.txt

test2.txt

test3.txt

test4.txt

[root@localhost tmp]# gzip all.tar   #重新把tar压缩成gzip格式

[root@localhost tmp]# ls all*

all.tar.gz

[root@localhost tmp]# ls clc* test*.txt    #被打包文件并没有消失

clc.dbaa  clc.dbac  clc.dbae   test2.txt  test4.txt

clc.dbab  clc.dbad  test1.txt  test3.txt

[root@localhost tmp]# rm -f clc* test*.txt

[root@localhost tmp]# tar -zxvf all.tar.gz     #解压gzip包,如果解压tar包则不用z选项

clc.dbaa

clc.dbab

clc.dbac

clc.dbad

clc.dbae

test1.txt

test2.txt

test3.txt

test4.txt

[root@localhost tmp]# ls clc* test*.txt

clc.dbaa  clc.dbac  clc.dbae   test2.txt  test4.txt

clc.dbab  clc.dbad  test1.txt  test3.txt


本文出自 “flyclc” 博客,请务必保留此出处http://flyclc.blog.51cto.com/1385758/1540164