Shell脚本正则表达式之Awk编程语言介绍+基本操作

awk基本语法介绍及操作

  • awk是一种处理文本文件的编程语言,文件的每行数据被称为记录,默认以空格或制表符为分隔符,每条记录会被分成若干字段(列),awk每次从文件中读取一条记录。

语法格式

awk [选项] '条件{动作} 条件{动作} ... ...' 文件名 ...

内置变量

变量名功能描述
FILENAME当前输入文档的名称
FNR当前输入文档的当前行号,尤其当有多个输入文档时有用
NR输入数据流的当前行号
$0当前的全部数据内容
$n…当前行的第n个字段的内容
NF当前记录行的字段列个数
FS字段分隔符,默认空格或TAB
OFS输出字段分隔符,默认为空格
ORS输出记录分隔符,默认为\n
RS输入记录分隔符,默认为\n
free
free | awk '{print $2}'    #逐行打印第二列
free | awk '{print NR}'  #输出行号
free | awk '{print NR}'  #输出每行数据的列数

在这里插入图片描述

vim test1.txt
hello the world!
My name is Cauchy, I can fly.
Seen is believing.

vim test2.txt
root:www:httpd
openstack::nova,api
fruit:apple,banana--peach:eat
awk '{print $0}' test1.txt      #打印全部内容
awk '{print}' test1.txt          #同上

在这里插入图片描述

#打印两个文件的行号
awk '{print NR}' test1.txt test2.txt
awk '{print FNR}' test1.txt test2.txt

在这里插入图片描述

  • NR与FNR的区别:NR会将所有文件的数据视为一个数据流,NR仅保存这些数据流递增的行号,而FNR是将多个文件的数据视为独立的若干个数据流,遇到新文件时行号会从1开始重新递增。
awk '{print NF}' test1.txt             #打印每行数据列数
awk '{print $NF}' test1.txt            #打印最后一列
awk '{print $(NF-1)}' test1.txt        #打印倒数第二列
awk '{print $(NF-2)}' test1.txt        #打印倒数第三列
awk '{print FILENAME}' test1.txt       #打印文件名

在这里插入图片描述

  • 为什么会输出三次文件名呢?
  • 答:awk是逐行处理软件,满足要求则执行动作指令

自定义变量

  • awk可以通过-v选项来设置或者修改变量的值。
awk -v x="Cauchy" '{print x}' test1.txt              #定义变量,输出变量值
awk -v x="Cauchy" -v y=25 '{print x,y}' test1.txt
awk -v x="Cauchy" -v y=25 '{print y,x}' test1.txt

在这里插入图片描述

x="dd"                              #自定义系统变量
awk -v i=$x '{print i}' test1.txt   #awk调用
y="jj"
awk '{print "'$y'"}' test1.txt      #awk调用

在这里插入图片描述
在这里插入图片描述

awk -v FS=":" '{print $1}' test2.txt    #重新定义分隔符号为“:”
awk -v FS=":" '{print $2}' test2.txt

在这里插入图片描述

  • 我们还可以用[]定义分隔符集合,如果有-分隔符千万不能放到中间,放到中间表示的是范围
awk -v FS="[:,-]" '{print $1}' test2.txt
awk -v FS="[:,-]" '{print $2}' test2.txt
awk -v FS="[:,-]" '{print $3}' test2.txt
awk -v FS="[:,-]" '{print $4}' test2.txt

在这里插入图片描述

  • -F可以直接指定数据字段的分隔符
awk  -F"[:,-]" '{print $1}' test2.txt
awk  -F: '{print $1}' test2.txt
  • RS保存的是输入数据的记录分隔符,默认值为\n换行符。
awk -v RS="," '{print $1}' test1.txt

在这里插入图片描述

  • 使用","作为分隔符符代替了\n换行符,则第一行数据为:hello the world!\nMy name is Cauchy。第二行数据为:I can fly.\nSeen is believing.。

  • OFS保存的是输出字段的分隔符,默认为空格;而ORS保存的是输出记录的分隔符,默认为\n换行符。

awk -v OFS=":" '{print $1 $2 $3}' test1.txt     #定义字段分隔符为冒号
awk -v OFS="-" '{print $1 $2 $3}' test1.txt     #定义字段分隔符为减号
awk -v OFS="\t" '{print $1 $2 $3}' test1.txt    #定义字段分隔符为制表符
awk -v OFS=". " '{print NR,$1}' test1.txt       #定义字段分隔符为点号和空格,并且打印出行号和$1内容

在这里插入图片描述

awk -v ORS="-" '{print}' test1.txt    #定义行分隔符为减号,并打印全部内容

在这里插入图片描述

print指令

  • print输出特定数据时,我们可以输出变量数据,同时还能直接输出常量,字符串常量需要用双引号。
 awk '{print "ABCD"}' test1.txt
 awk '{print "ABCD",$1}' test1.txt
 awk '{print 1234}' test1.txt
 awk '{print $1,1234,$3}' test1.txt
 awk '{print "第一列:"$1,"\t第二列:"$2}' test1.txt

在这里插入图片描述

条件匹配

  • awk支持正则进行模糊匹配,也支持字符串和数字精确匹配,并支持逻辑与,或。
比较符号功能描述
//全行数据正则匹配
//!全行数据正则匹配后取反
~//对特定数据正则匹配
!~//对特定数据正则匹配后取反
==等于
!=不等于
>大于
>=大于等于
<小于
<=小于等于
&&逻辑与
ll逻辑或
awk '/hello/{print}' test1.txt       #打印包含hello的行
awk '/hello/' test1.txt              #打印包含hello的行
awk '/name/' test1.txt               #每行正则包含name

在这里插入图片描述

awk '$2~/the/' test1.txt                    #每行第二列正则匹配the
awk '$2~/name/{print $1,$3,$5}' test1.txt   #每行第二列正则匹配the,并打印其1,3,5列

在这里插入图片描述

vim test3.txt
I like reading book
I will go to the hospital
I wont work too much homework
awk '$4~/to/' test3.txt     #正则匹配第四列包含to的行
awk '$4=="to"' test3.txt    #精确匹配
awk '$2!="like"' test3.txt  #第二列不等于like

在这里插入图片描述

awk -F: '$3<=10' /etc/passwd                #匹配第三列小于等于10的行
awk -F: '$3>=100' /etc/passwd               #匹配第三列大于等于100的行
awk -F: '$3<=10{print $1}' /etc/passwd      #匹配第三列小于等于10的行,并打印第一列
awk 'NR==4' /etc/passwd                     #仅显示第四行数据元素
awk -F: '$3>1&&$3<5' /etc/passwd            #逻辑与
awk -F: '$3==1||$3==5' /etc/passwd          #逻辑或

在这里插入图片描述

  • awk的匹配条件是BEGIN和END,BEGIN会导致动作指令仅在读取任何数据记录之前执行一次,END会导致动作指令仅在读取完所有的数据记录之后执行一次,BEGIN初始化操作,END数据汇总操作。
 awk 'BEGIN{print "OK"}'
 awk 'BEGIN{print "OK"}' /etc/passwd
 awk 'END{print NR}' /etc/passwd 

在这里插入图片描述

awk -F: 'BEGIN{print "用户名\tUID\t解释器"} \
{print $1"\t",$3"\t",$7} \
END{print "总计有"NR"个账户."}' /etc/passwd

在这里插入图片描述
在这里插入图片描述

  • awk的算术运算
 awk 'BEGIN{print 1+1}'
 awk 'BEGIN{print 1-1}'
 awk 'BEGIN{print 1*1}'
 awk 'BEGIN{print 3/8}'
 awk 'BEGIN{print 3%8}'
 awk 'BEGIN{print 2**8}'

在这里插入图片描述

awk 'BEGIN{x=6;y=3;print x+y}'
awk 'BEGIN{x=6;y=3;print x-y}'
awk 'BEGIN{x=6;y=3;print x*y}'
awk 'BEGIN{x=6;y=3;print x/y}'
awk 'BEGIN{x=6;y=3;print x%y}'
awk 'BEGIN{x=1;x++;print x}'
awk 'BEGIN{x=1;x--;print x}'
awk 'BEGIN{x=2;x*=2;print x}'
awk 'BEGIN{x=2;x/=2;print x}'
awk 'BEGIN{x=2;x%=2;print x}'

在这里插入图片描述

  • 未定义变量默认值为0,字符串为空

在这里插入图片描述

  • awk统计用法
awk '/bash$/{x++} END{print x}' /etc/passwd
who | awk '/root/{x++} END{print x}'

在这里插入图片描述

seq 200 |awk '$1%7==0 && $1~/7/'    #统计200以内被7整除且数字中带有7的元素

在这里插入图片描述

df |tail -n +2 |awk '{sum+=$4} END{print sum}'                 #统计磁盘总量
ls -l /etc/*.conf |awk '{sum+=$5} END{print sum}'              #统计conf配置文件总量
ls -l /etc/ |awk '/^-/{sum+=$5} END{print "文件总量为:"sum"."}'  #统计普通文件总量(普通文件为-)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值