shell编程之sed和awk命令

grep、sed、awk是shell脚本编写中最常用到的三个工具

因为grep平时已经很熟悉了,这里就不介绍了,主要讲讲sed和awk工具

sed是一个”流处理编辑器”,可以用于自动处理文件,分析日志文件,修改配置文件,它接收文本或管道的输入,读入一行到模式空间(临时缓冲区),sed命令处理行,最后输出到屏幕,然后再次读入一行,继续上面流程,直到读完为止

使用sed的格式:

命令行格式:sed [options] ‘命令’ file(s)

脚本格式:sed -f scriptfile file(s) tip:命令还可以写在一个脚本文件里调用

options有 -n 、-e是比较常用的,命令:行定位(正则)+sed命令(操作)

p命令:打印行命令

例子:sed -n '5p' hello.txt

5代表第五行,打印第五行的内容,-n表示打印出命令操作的行,不加-n会打印出所有的行(包括经过操作之后的行)

不光可以用行号选择行,还可以用正则方式选择:sed -n '/wu/p' hello.txt,注意:正则表达式要用//两个斜杠包含在中间

 上面是定位一行,还可以定位多行:sed -n '3,8p' hello.txt(打印出第三到第八行的内容)

当然行号也可以用正则替代:sed -n '/pid/,/hehe/p' hello.txt

还可以进行取反操作:sed -n '3!p' hello.txt(将除了第三行以外的行打印出来)



a命令:新增行命令

 例子:sed '5a *************************' hello.txt

 a命令将在第五行之后添加新的一行,内容为**************************

同样的,sed '1,5a ##############' hello.txt,将在第一到第五每行的后面都添加新的一行,行号也同样可以用正则替代

例子2:sed '$a \ port:9001 \n loginName:haha' config

解析:sed命令将在config文件的末尾($),添加新的两行(有\n),\n到login之间的空格也同样会打印在新的一行,至于port之前的空格,因为

a命令和内容之间本来就有空格,所以以\表示内容的开始,\到port之间的空格就是第一行前面的空格



i命令:插入行命令


 例子:sed '5i *************************' hello.txt

 i命令将在第五行之前添加新的一行,内容为**************************


c命令:替换行命令


例子:sed '5c *************************' hello.txt

c命令会将第五行替换成**************************

 注意:sed '1,5c **************'  hello.txt,不是将第一到第五每行都替换成*******,而是将第一到第五这五行替换成************

d命令:删除行命令

例子:sed '5d' hello.txt

d命令将删除第五行

例子2:sed '/^$/d' hello.txt

删除文本文件中的空行,/^$/代表空行



s命令:替换字符串命令

格式:s+分隔符+旧字符串+分隔符+新字符串+分隔符,分隔符可以是/或#等等

旧字符串当然也可以用正则来匹配

例子:sed 's/false/true/' passwd,将passwd文件中的每一行的第一个false替换成true,若你想让每一行的所有false都替换成true,则只需

sed 's/false/true/g' passwd,加上g选项将替换每一行所有的匹配的字符串



&符号:替换固定字符串

配合s命令使用

例子:sed 's/^[a-z]\+/& /' passwd

将passwd文件中,以[a-z]\+为开头的行的[a-z]\+替换成原来的字符串加上若干空格,&就是代表前面的旧字符串



()符号:提取字符串

同样配合s命令使用

例子:sed 's/\(^[a-z_-]\+\):.*$/\1/'  passwd

首先匹配[a-z_-]\+开头的行,这里还用\(\)将开头括了起来,注意反斜杠的转义,标注我们要提取它,在后面用\1表示我们要提取第一个
用()括起来的子字符串,如果还有第二个(),则用\2表示

总之就是首先用正则匹配你需要的行,用()括起你想提取的字符串,最后用\1,\2等等表示你要提取的字符串

awk也是一个文本与数据处理工具,但是awk是可编程的,更灵活强大

awk的处理方式和格式:
awk一次处理一行内容,而且对每行可以进行切片处理
格式与sed差不多:
命令行格式:awk [options] ‘{command}’ file,而command格式:pattern{awk操作命令}
pattern:正则表达式和逻辑判断式
awk操作命令:内置函数:print()、printf()、getline()……..控制指令:if(){…..}else{…..};while(){…….};
脚本格式:awk -f scriptfile file(s)

awk内置参数应用:

awk内置变量:

扫描二维码关注公众号,回复: 1894549 查看本文章
- $0:表示整个当前行
- $1:表示每行第一个字段
- $2:表示每行第二个字段
....以此类推
- NR:每行的记录号(行号)
- NF:每行的字段数
- FILENAME:正在处理的文件名

awk内置参数:分割符

    options: -F  filed-separator(不指定,默认为空格)
    例如:awk -F ':'  '{print $3}'  /etc/passwd
    在passwd文件中,以每行的:(冒号)为分割符,打印出每行的第三个字段,print命令会在打印一行之后,默认换行
    若要打印多个字段:awk -F ':'  '{print $1,$2,$3}'   /etc/passwd,以逗号分隔的话,则在打印出的字段之间会以空格分隔,根据print工具的用法,也可以打印制表符:print $1 "\t" $2来分隔字段,也可以加些说明文字,awk -F ':'  '{print "user:"$1"\t""pass:"$2}'   /etc/passwd。awk制表的原理差不多就是这样来的
    除了用print还可以用printf()来打印,例子:awk -F ':' '{printf("Line:%3s Col:%s User:%s\n",NR,NF,$1)}' passwd,就像C++里的printf()一样

awk控制指令:

if(){…..}else{…..};while(){…….};
例子:awk -F ‘:’ ‘{if ( 3 > 100 ) p r i n t " L i n e :" N R , " U s e r :" 1}’ passwd
若每行的第三字段大于100则输出那行的行号和字段1

pattern:
之前提到command格式:pattern{awk操作命令},pattern有正则表达式和逻辑判断式

逻辑判断式:

例子:awk -F ':'  '$2==100{print $1,$3}'  passwd
若当前的第二字段等于100则输出$1和$3,当然也有<,>,<=,>=,!=

正则表达式:

例子1:awk -F ':' '/ERROR/{print  $1}'  test.log
输出匹配/ERROR/正则的那行的第一个字段

例子2:上面是用整行来匹配正则,当然也可以用某个字段来匹配
比如:awk -F ':'  '$2~/^m.*/{print $0}'  passwd,循环遍历每行,若第二个字段匹配/^m.*/则输出那行,若是判断"不匹配",则用!~

awk扩展格式:

例子:awk -F ':'  'BEGIN{print "Line    Col     User"}{print NR"\t"NF"\t"$1}END{print "------"FILENAME"------------"}'  passwd
制表显示每行的行号,每行列数,对应行的用户名
{print "Line    Col     User"}输出表格的表头,{print "------"FILENAME"------------"}输出表的表尾

例子2:统计当前目录下所有文件的大小

ls -l  |  awk 'BEGIN{size=0}{size+=$5}END{print  "size  is "size/1024/1024"M" }'

例子3:统计passwd中的账户总数

awk -F  ':'   'BEGIN{count=0}$0!~/^$/{count++}END{print "count= "count}'  passwd

例子4:统计显示UID>100的用户名

awk -F ':'  'BEGIN{count=0}{if ($3>100) name[count++]=$1}END{for(i=0;i<count;i++)  print i,name[i]}'   passwd

例子5:统计netstat -anp状态下分别为LISTEN和CONNECTED的连接数

netstat -anp  |   awk '$6~/CONNECTED|LISTEN/{sum[$6]++}END{for (i in sum)print  i,sum[i]}'

awk和sed比较:
awk和sed都能处理文本
awk侧重于复杂逻辑处理
sed侧重于正则处理
当然他们也可以共同使用!

猜你喜欢

转载自blog.csdn.net/qq_33535433/article/details/79238141