awk入门(二)

本文的使用的示例文件

~]$ cat a.txt
ID  name    gender  age  email          phone
1   Bob     male    28   abc@qq.com     18023394012
2   Alice   female  24   def@gmail.com  18084925203
3   Tony    male    21   aaa@163.com    17048792503
4   Kevin   male    21   bbb@189.com    17023929033
5   Alex    male    18   ccc@xyz.com    18185904230
6   Andy    female  22   ddd@139.com    18923902352
7   Jerry   female  25   exdsa@189.com  18785234906
8   Peter   male    20   bax@qq.com     17729348758
9   Steven  female  23   bc@sohu.com    15947893212
10  Bruce   female  27   bcbd@139.com   13942943905

修改字段或NF产生的联动效应

1.在使用awk进行输出时,如果修改了字段的值或者修改了变量NF,那么awk在输出的时候就会重新以OFS为间隔输出每条记录。
2.OFS可以自定义设置,如果不设置则默认为空格。
3.如果先修改字段或者NF,然后才设置OFS,那么第一行就不会以新设置的OFS为间隔,而是以默认的空格为间隔
4.使用$0=$0不能导致重新划分字段
想要重建之后的所有行都生效,那么最好先设置OFS再进行重建

~]$ awk '{$1=$1;print $0}' a.txt  ##这样输出其实对文件已经产生了修改,OFS从制表符变成了空格
~]$ awk '{OFS="*";$1=$1;print $0}' a.txt ##这样就会以*号为间隔重新输出每一条记录
~]$ awk '{$1=$1;OFS="*";print $0}' a.txt ##这样设置,第一行的间隔仍然是以空格为准的,因为先设置的$1=$1,
										 ##所以已经导致了当前行的重建,因此间隔符仍然以默认的为准
~]$ awk '{OFS="*";NF=1;print $0}' a.txt  ##设置NF的值为1,导致$0重建,不过输出时也只有第一列数据
										 ##相当于先获取第一列数据作为一个整体内容,然后再输出$0就只有ID这一列数据了
~]$ awk '{OFS="*";NF-=2;print $0}' a.txt ##NF修改导致$0重建,并且只获取前(6-2)4列的数据
~]$ awk '{OFS="*";$(NF+2)=5;print $0}' a.txt ##这样会新产生两个字段,并且$(NF+2)字段的值为5,这样也会产生$0重建

示例

使用$0重建来压缩文件中的空格
~]$ echo "a   b c         d    e     " | awk '{$1=$1;print $0}'
~]$ echo "a   b c         d    e     " | awk '{$1=$1;print $0}' OFS="-"
~]$ echo "a   b c         d    e     " | awk '{OFS="";$1=$1;print $0}' #OFS可以随意设置

awk数据筛选

1.按记录筛选
2.按字段筛选
3.按正则表达式筛选
4.定址的方式筛选
5.多条件组合筛选

1.按记录筛选,可以根据NR变量来进行判断,从而筛选指定的记录号
~]$ awk 'NR==3{print $1,$2,$3}' a.txt ##这样就可以只输出第三条记录中相应的字段了
2.按字段筛选
~]$ awk 'NR==1{print $1}' a.txt ##只输出第一条记录的第一个字段
~]$ awk '($1+0)>5{print $2}' a.txt ##将$1隐性转换到整型,然后筛选$1字段大于5的记录,并且输出$2字段
									## 默认情况下,如果$1为数字,那么它的类型为strnum
									## 转换后就变成了number,可使用'{print(typeof($1))}'; '{print(typeof($1+0))}'
~]$ awk '$2 ~ /\<A.*x\>/{print $6}' a.txt ##筛选$2字段满足此正则表达式的记录,并且输出该记录的$6字段
										 ## \< \>的用法用于匹配一个单独的单词(单词前后都是空白)
3.使用正则表达式匹配
~]$ awk '/Alice/{print $0}' a.txt #匹配范围为整个记录
~]$ awk '/A.*/{print $0}' a.txt #匹配包含字母A,且后面有其他内容的
~]$ awk '/A.*y/{print $0}' a.txt
~]$ awk '/A[[:alpha:]]+y/{print $0}' a.txt
~]$ awk '/\<A.*y\>/{print $0}' a.txt  ##使用正则表达式最为灵活,可以根据需要灵活使用
4.定址
~]$ awk 'NR==1 || NR==3{print $1}' a.txt ##若记录数是第一或第三条记录,那么就输出该记录的$1字段
~]$ awk 'NR==1,NR==3{print $0}' a.txt ##输出前三条记录
~]$ awk 'NR==1,$6 ~ /170*/{print $0}' a.txt  ##输出从第一条记录开始到$6字段以170开头的记录
5.多条件组合筛选,以上示例中很多都是多条件组合筛选的
~]$ awk '$1 > 3 && $3 ~ /female/{print $2}' a.txt

示例

筛选ifconfig命令结果中除lo网卡之外的所有网卡的ip地址:本文仅讨论awk的筛选方式,其他方式暂不讨论
方式一:
	~]$ ifconfig | awk 'BEGIN{RS="^$"}{print $6}' #这个是根据^$这个特殊分隔符来获取全文内容,然后根据空格来获取字段
方式二:
	~]$ ifconfig | awk '/inet / && !/127.*/{print $2}' #先筛选出ip那一行,并过滤127.0.0.1这个ip
方式三:
	~]$ ifconfig | awk 'BEGIN{RS="";FS="\n"}NR==1{$0=$2;FS=" ";$0=$0;print $2}' ##通过字段重建的方式来筛选,这个有点麻烦

awk工作流程

1.解析 -v var1=value…中的变量声明
2.编译awk源代码为awk可解释的内部各式,包括-v变量
3.执行BEGIN代码段
4.根据RS来读取文件,如果没有指定文件,那么就从标准输入中读取文件,同时执行main代码段:

  • 如果在文件名部分声明变量,此阶段的变量在BEGIN之后声明的,因此此变量在BEGIN段中不可用,在main段中可用
  • 每读取一条记录:
    (1)都将设置NR,FNR,RT,$0等变量
    (2)根据FS切割每条记录的字段,并保存至$1,$2,$3…等变量中
    (3)测试main代码段中的pattern部分,测试成功则执行action部分,pattern可以有多个,每个未声明action的pattern都有一个默认action,此默认action为{print $0}。

5.执行END代码段

~]$ awk 'BEGIN{print "hello"}{print $0}END{print "end"}' a.txt ##这样就会在每个记录之前输出“hello”,
## 在输出每条记录后输出出“end”,另外hello和end需要双引号包围,不然awk当做变量处理,从而输出为空行
hello
ID  name    gender  age  email          phone
end
1   Bob     male    28   abc@qq.com     18023394012
end
2   Alice   female  24   def@gmail.com  18084925203
end
3   Tony    male    21   aaa@163.com    17048792503
end
4   Kevin   male    21   bbb@189.com    17023929033
end
5   Alex    male    18   ccc@xyz.com    18185904230
end
6   Andy    female  22   ddd@139.com    18923902352
end
7   Jerry   female  25   exdsa@189.com  18785234906
end
8   Peter   male    20   bax@qq.com     17729348758
end
9   Steven  female  23   bc@sohu.com    15947893212
end
10  Bruce   female  27   bcbd@139.com   13942943905
end
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值