微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 微电子和IC设计 > IC验证交流 > sed和awk的简单学习笔记

sed和awk的简单学习笔记

时间:10-02 整理:3721RD 点击:

之前我做一些基本的文本处理也都是喜欢用perl来写脚本实现。这样做还是比较麻烦,效率也不高,其实可以使用SED和AWK的一些基本(组合)命令来实现。

SED和AWK也可以支持脚本,不过如果要写脚本的话,我倒更愿意去写Perl的脚本了。所以下面的例子基本都是一行命令的处理例子。

-------------- SED---------------

例子1:

给每一行后面都加一行“000”的行---》比如,NE的testpattern全是y的,需要给它加上uv分量。

sed -e 'a\\

? 000' t.txt

注意:上面是2行,必须用换行符,否则就得用sed脚本-f了

如果是每2行增加2行00:

sed -e 'n;a\\

?00\n00' tt.txt

例子2:

删除奇数行(只要偶数行)

sed -n -e 'n;p' t.txt

分析: -n是不打印,如果不加-n,会导致偶数航被打印2次。 'n;p'的意思是下一行打印。用这个方式来剔除了奇数行

例子3:

删除偶数行(只要奇数行)

sed-e 'n;d' t.txt

分析: 用d直接把偶数行删除了

例子4:

只打印指定字符串"lisj"的行(类似于grep)

sed -e '/lisj/p' -n t.txt

例子5:

删除第一行

sed -e '1d' t.txt

删除第1到第4行

sed -e '1,4d' t.txt

删除第1行到第一个包含指定字符串“study”的行

sed -e '1,/study/d' t.txt

删除第一个包含指定字符串“compiler”到第一个指定字符串“study”的行

sed -e '/compile/,/study/d' t.txt

例子6:

为每一行前面加上“[ ]”

sed 's/^/[ ]/g' t.txt

为每一行后面加上"[ ]"

sed 's/$/[ ]/g' t.txt

例子7:

显示匹配行的行号

sed '/sed/=' t.txt

sed '/sed/=' -n t.txt

注意:如果不加-n选项,则会打印整个文件和匹配行的行号。加了-n就会只打印匹配行的行号

sed -n-e '/sed/=' -e '/sed/p' t.txt

分析: 这样就会打印匹配行的行号和匹配航的内容

sed -n -e '/sed/p' -e '/sed/=' t.txt

分析: 只是与上面命令的显示顺序不一样

例子8:

限定范围以后的模式匹配和替换。 把所有包含指定字符串“sed”的行里的第一个e改成“EE”

sed '/sed/s/e/EE/' t.txt

例子9: &用法,获取前面匹配的内容

把“sed”,换成“sed ABC”

sed 's/sed/& ABC/' t.txt

把所有含“sed”的行用()括起来

sed '/sed/s/.*/(&)/' t.txt

例子10: \1用法,类似于perl的匹配时候的$1

把每行里第一个“li”替换成“li+gyl”

sed 's/\(li\)/\1+gyl/' t.txt

注意: \(li\)

例子11:只打印1到4行里包含“sed”的行

sed -n -e '1,4p' t.txt | sed -n -e '/sed/p'

例子12:!用法

只保留文件的1到4行

sed -e '1,4\!d' t.txt

注意: 我发现得用\!来转义,但是书上看到的例子却没有用转义

-----------------AWK----------

假设t.txt内容是:

namebirthdayagegenderbegin_working

lishujie1980/10/1732Male24

gongyanli1981/10/2031Female26

liyuxuan2008/09/214Female4

例子:把一个文件的第一行去掉,然后选取每行的第一个域和第四个域,并且在文件一开始增加内容,文件末尾增加内容

sed '1d' t.txt | awk 'BEGIN {print "Namegender \n----------------"}{print $1,$4} END {print"End-of-print"}'

注意:AWK默认以空格来区分域。如果不是空格的话需要用 -F seperate-operator来指定。

AWK里的正则匹配~ 不匹配!~

例子:把匹配某字符串的行打印出来

awk '{if($4~/Female/) print $0}' t.txt

注意:$0是指的把正行都打印出来。if实现精确的匹配,也可以不用if。比如上述命令简化为 awk '$0 ~ /Female/' t.txt

再比如:

awk '$3 == 31' t.txt

awk '/^li/' t.txt

awk '{if($3 == 31 && $1=="gongyanli") print $0}' t.txt

awk '{if($3 == 31 || $1=="lishujie") print $0}' t.txt

AWK里的内置变量。内置变量比较多,建议看参考书。举几个例子:

FILENAMEawk浏览的文件名

FNR 浏览文件的记录数

FS 设置输入域分隔符,等价于命令行- F选项

NF浏览记录的域个数

NR已读的记录数

例子:获取文件行数

awk 'END{print NR}' t.txt

例子:在每行前面加上 域个数、行号;在最后加上文件名信息

awk '{print NF,NR,$0} END {print FILENAME}' t.txt

例子:从PWD中抽取文件夹名

echo `pwd` | awk -F / '{print $NF}'

给域设置域变量名,方便使用

awk '{name=$1;age=$3;if(name=="lishujie") print name"'\''s age is "age}' t.txt

注意:这里牵扯到了如何在AWK里打印单引号的问题。

解决方法是 把转义的单引号 ‘ 用两个单引号括起来并且加上转义符号,使其不执行

设置局部的变量:

awk '{name=$1;age=$3;max_age=31 ;if($3<max_age) print name"'\''s age is "age}' t.txt

在awk里实现运算:

awk '{name=$1;age=$3 ;age=age+1; if (name !~ /name/) print "Next year "name"'\''s age is "age}' t.txt

修改域值:

awk '{if ($1 ~ /lishujie/) $1 = "dad" ; if ($1 ~ /gongyanli/) $1 = "mum" ;print $0}' t.txt

这个还是会把所有的记录都打印出来,如果想只打印修改的记录怎么处理呢?

awk '{if ($1 ~ /gongyanli/) {$1 = "mum" ;print $0}}' t.txt

注意: 使用大括号来设置命令的执行范围就可以了。

增加一列参数“working_year” 并且计算数值。

第一行表头处理方法:

awk '{if (NR == 1) printf "%s\t working_year\n",$0}' t.txt

注意:这里用printf来实现去掉$0里的换行符。

后面数据处理方法:

awk '{if (NR > 1) {working_year = $3-$5;printf "%s\t%d \n",$0,working_year}}' t.txt

把上述两个命令合并在一起就可以了

awk '{if (NR == 1) printf "%s\t working_year\n",$0} {if (NR > 1) {working_year = $3-$5;printf "%s\t%d \n",$0,working_year}}' t.txt

统计列值的累加值:

awk '{tot+=$3;print $0}END{print "tot age is "tot}' t.txt

不打印文件内容,只统计列值的话,就不要“print $0”

awk '{tot+=$3}END{print "my family total age is "tot}' t.txt

嚓,不好意思,word文档里的空行帖子里都没了。

高手啊啊啊啊啊

sed和awk对文本的处理效率还是挺高的,赞一个,好好学习。

gao shou

学习中,谢谢分享。

非常有用哦。

真是个好论坛啊

熟悉sed和awk可以方便很多啊

学习学习!

以前不太懂也不太会用sed awk,现在发现这个简直就是神器啊,可以省不少的力

mark!thanks!

学习了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top