700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 正则表达式-awk和sed两个工具的使用

正则表达式-awk和sed两个工具的使用

时间:2018-08-13 05:37:03

相关推荐

正则表达式-awk和sed两个工具的使用

正则表达式

================================

1.作用

用人为规定一些特殊符号表示匹配字符串

适用场景:模糊匹配字符串

元字符: 正则表达式中具有特殊含义的字符,叫做元字符

2.常用的元字符

grep "^he" 1.txt -Hn //匹配行首he

(1) 逻辑或需要转义

grep "he\|ha" 1.txt -Hn

(2)不出现,或者出现一次 ?需要转义

grep "hel\?o" 1.txt -Hn

问号需要转义

l\?表示l不出现,或者l出现一次

(3)出现一次,后者出现多次 +需要转义

grep "hel\+o" 1.txt -Hn

(4)指定重复次数 {}左右两边需要转义

grep "hel\{2,4\}o" 1.txt -Hn

awk和sed两个工具的使用

================================

1.awk处理表格中列

安装awk: sudo apt-get install awk

作用:主要用于统计表格中的信息,打印列

注意的要点:

第一: 搜索字符串

awk '$0~/你要匹配的字符串/ {print}' 要搜索的文件名

.* 表示匹配任意长度的字符串

2.sed也能处理表格数据

安装sed: sudo apt-get install sed

作用:字符串的增删改查都可以

命令总结:

第一:替换

sed "s/旧字符串/新的字符串/" people.txt

awk编程入门

测试文档:(grade.txt)

M.Tansley 05/ 48311 Green 8 90

J.Lulu 04/ 48317 green 12 88

P.bunny 02/ 48 Yellow 9 70

J.Troll 09/ 4842 Brown-3 11 95

L.Tansley 05/ 4712 Brown-2 10 85

Vincent 07/ 4712 Brown 13 87

1,打印指定列(例如名字和年龄)

awk '{print $1,$5}' grade.txt

注意:其中单引号中的被大括号括着的就是awk的语句,只能被单引号包含。

其中的$1..$n表示第几例。$0表示整个行。

注意:awk的工作次序是:首先读取grade.txt文件一个记录(即一行),然后根据单引号内部的指令工作,完了之后继续读下一行,以此类推。每读一行都会将单引号里面的语句从头到尾地应用到那一行中去。

2,格式化输出(和C语言一样一样的)

awk '{printf"%-10s:%-d\n", $1,$5}' grade.txt

3,过滤

awk '$5==11 && $6>=90 {print $0}' grade.txt

意思是==>打印出年龄等于11岁且分数大于90分的孩子的信息

4,打印表头,引入内建变量NR

awk 'NR==1 || $6>=90 {print}' grade.txt

注意:NR是一个所谓的内建变量,表示已经读出的记录数(即行号)

其它有用的内建变量是:

5,指定分隔符

awk ‘BEGIN{FS=”:”} {print $1}’/etc/passwd

注意:BEGIN意味着紧跟在它后面的语句{FS=:}会在awk读取第一行之前处理。

上面的语句等价于

awk -F: ‘{print $1}’/etc/passwd

如果有多个分隔符,则可以写成

awk -F’[\t;:]’‘{print $1}’/etc/passwd

6,使用正则表达式匹配字符串

awk '$0~/Brown.*/ {print}' grade.txt 意思是==>将所有包含Brown的行打印出来

注意:波浪号~后面紧跟着一对正斜杠,表示所指定的域(这里是$0)要匹配的规则

7,使用模式取反的例子

awk '$0!~/Brown.*/ {print}' grade.txt 意思是==>将所有不包含Brown的行打印出来

拆分文件

8,将各年龄段的孩子的信息分别存放在各个文件中

awk 'NR!=1 {print > $5}' grade.txt

意思是==>表头不处理,后面的每一行,都将被重定位到以第5个域(年龄)命名的文件中去。

也可以将指定的域重定位到相应的文件

awk 'NR!=1 {print $1, $6 > $5}' grade.txt

意思是==> 不处理表头,将每一行中的姓名和分数重定位到与其年龄相应的文件中去。

9,再复杂一点,按级别将信息分成三个文件:

awk'NR!=1{if($4~/Brown.*|Black/) print > "high.txt";

else if($4~/Yellow|[Gg]reen/) print > "midle.txt";

elseprint > "low.txt"}'grade.txt

意思是==> 如果记录中的第4个域($4)匹配Brown.*或者Black,就将该记录重定位到文件high.txt中,如果匹配Yellow或者[Gg]reen,就重定位到midle.txt中,否则统统重定位到low.txt中。

统计

10,将所有孩子的分数累积起来并打印出来

awk '{sum+=$6} END{print sum}' grade.txt

注意:END表示->紧跟其后的语句只会在awk处理完所有行之后才被执行。

11,统计各个级别的人数

awk 'NR!=1 {a[$4]++;} END{for(i in a) print i","a[i];}' grade.txt

注意:$4是级别名称,例如Yellow、Brown等,a是一个以这些级别为下标的数组,其值从零开始计算。i就是Yellow、Brown等a[i]是对应有几个Yellow、Brown 中间用逗号隔开

awk脚本

12,想象我现在要打印出整个班级的所有孩子的信息,而且在最前面把表头也打印出来,而且下面要打印一行“===========”来跟具体内容加以划分。并且在最后一行,统计孩子们的平均年龄以及平均分数。将awk语句组织成脚本,如下:

#!/usr/bin/awk -f

#/usr/bin/awk指定脚本解释器的位置,-f表示运行该脚本需要指定一个文件作为输入

BEGIN{ #awk开始运行之前的准备工作(定义了两个变量),此左花括号必须紧跟BEGIN

age = 0

score = 0

}

{

if(NR==1) #打印表头已经分割线

{

print $0

printf "==============================" #由于是printf,没有\n就不换行

print "==============================" #由于是print,会自动换行

}

else

{

age+=$5

score+=$6

print $0

}

}

END{ #awk处理完所有的记录之后,END才开始运行

printf "=============================="

print "=============================="

print "Average:\t\t\t\t\t" age/NR ",\t" score/NR

}

关于sed

测试文档:(people.txt)

Jack is 18-year old, he comes from US.

Mike is 16-year old, he comes from Canada.

Chen is 21-year old, he comes from China.

Lau is 18-year old, he comes from HongKong.

Michael is 20-year old, he comes from UK.

Phoebe is 18-year old, she comes from Australie.

1,替换:

例如,将"-year"改成" years":

sed "s/-year/years/" people.txt

2,指定某些行替换:

例如,将第2行的"-year"改成" years":

sed "2s/-year/years/" people.txt

再如,将第2至5行的"-year"改成" years":

sed "2,5s/-year/years/" people.txt

3,直接通过sed修改原文,加选项 -i:

sed -i "2s/-year/years/" people.txt

注意:sed缺省状态下不会修改原文

4,替换每一行中的所有的小写s成大写S:

sed "s/s/S/g" people.txt

注意:g的意思是一行中所有的匹配项,否则缺省只会匹配第一个s

5,替换每一行中的第2个小写s成大写S:

sed "s/s/S/2" people.txt

6,替换每一行中的第2个以后的小写s成大写S:

sed "s/s/S/2g" people.txt

多个匹配

7,将"-year"改成" years",并且将第3行以后的最后一个任意字符去掉:

sed 's/-year/ years/; 3,$s/.$//' people.txt

以上命令等价于:

sed -e 's/-year/ years/' -e '3,$s/.$//' people.txt

注意:在单引号里面,元义字符可以直接使用,如果要去掉元义则要在前面加\ ; 在双引号里面,sed的命令要使用元义,则需要加\ , 而命令的正则表达式要使用元义直接使用就行。

8,将&代替被匹配的变量:

sed "s/is/[&]/" people.txt

意思是==>:将文本中每一行出现的第一个is的左右两边加上[ ]

9,如果使用正则表达式匹配项的时候使用了圆括号括了起来,那么可以用\1,\2,\3……等来表示这些项:

sed "s/\(^.*\)\tis.*from \(.*\)./\1\t:\2/g" people.txt

分解一下:

1,其中加粗的\(^.*\)\tis.*from \(.*\).是正则表达式,简化一下是(^.*)\tis.*from (.*). 在这个表达式中,制表符\t前面的匹配项可以被记为\1,from后面的匹配项可以被记为\2

2,后面加下划线的\1\t:\2部分是替换的字符串,也就是只打印匹配出来的名字和国籍,中间用制表符和冒号隔开。

10,提前预读多一行缓冲来进行匹配:

sed 'N;s/is/IS/' people.txt

注意:由于替换只会针对第一个出现的单词is,而通过N又多读了一行,因此这个命令的结果是只会替换奇数行。

11,在指定行的前面插入(i)或者后面插入(a)一些信息:

sed '3i abcd' people.txt 意思是==>在第3行的前面插入abcd

sed '2a abcd' people.txt 意思是==>在第2行的后面插入abcd

sed '1,4a abcd' people.txt 意思是==>在第1至4行的后面分别插入abcd

sed '/US/a abcd' people.txt 意思是==>在匹配US的行的后面插入abcd

12,将指定的行替换成其他信息:

sed "2c ok" people.txt 意思是==>将第2行替换成ok

13,将指定的行删除掉:

sed ‘2d’ people.txt 意思是==>将第2行给删掉

sed ‘/US/d’ people.txt 意思是==>将匹配/US/的所有行给删掉

sed '/\<he\>/d' people.txt 意思是==>将匹配he的所有行给删掉,注意:之所以要用<>将he给括起来,是因为不想匹配she,当然,<>需要转义,写成\<\>

14,打印指定匹配的行,用命令p:

sed '/Chen/p' people.txt -n 意思是==>打印匹配Chen的行

sed '/Chen/, /Lau/p' people.txt -n 意思是==>打印匹配Chen或者Lau的行

sed '3,/UK/p' people.txt -n 意思是==>从第3行开始打印,直到匹配UK为止

sed '/UK/,6p' people.txt -n 意思是==>从匹配UK的行开始打印,直到第6行为止

15,使用相对位置:

sed '/US/, +2p' people.txt -n 意思是==>打印匹配US的行,并打印其后的2行。

16,执行多个命令:

sed '{/he/{/18/p}}' people.txt -n 意思是==>匹配所有/he/的行之后,再匹配/18/的行,然后打印出来。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。