AWK的学习使用。

awk的学习使用

awk是一门文本处理语言,功能强大,用法灵活,而且还可以处理一些cut无法完成的操作。下面是我结合网络上的资料,以及自己的实践的一些示例,对用法的一些总结。

一、常用参数与选项含义

 $0           表示整个当前行
$1           每行第一个字段 NF 字段数量变量 NR 每行的记录号,多文件记录递增 FNR NR类似,不过多文件记录不递增,每个文件都从1开始 \t 制表符 \n 换行符 FS BEGIN时定义分隔符 RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入) ~ 匹配,与==相比不是精确比较 !~ 不匹配,不精确比较 == 等于,必须全部相等,精确比较 != 不等于,精确比较 &&  逻辑与 || 逻辑或 + 匹配时表示1个或1个以上 /[0-9][0-9]+/ 两个或两个以上数字 /[0-9][0-9]*/ 一个或一个以上数字 FILENAME 文件名 OFS 输出字段分隔符, 默认也是空格,可以改为制表符等 ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕 -F'[:#/]' 定义三个分隔符

说明:NF,NR,FS,RS是awk的内置变量,可以对输出做一些控制,下面部分例子中会有用到。

二、用法举例

我的测试文本: 
root@newbie-unknown85880:/tmp# cat test.txt 
abc bb cc 
a1 b1 c1 
a2 b2 c2 
12 20 30

1、执行方式:

awk可以通过命令行方式执行,其实还可以写成脚本的方式跑。

命令行:

root@newbie-unknown85880:/tmp# awk '{print $0}' test.txt  abc bb cc a1 b1 c1

-f 指定程序体:

root@newbie-unknown85880:/tmp# awk -f awk-test.awk  hello world

程序内容为:

root@newbie-unknown85880:/tmp# cat awk-test.awk  BEGIN{print "hello world"}

脚本方式执行

awk -f awk脚本文件名 被处理文件名

2.awk对输出域/列的控制

一般文本有很多列,我们要对其实现部分列的输出有:

全部输出:

root@newbie-unknown85880:/tmp# awk '{print $0 }' test.txt  abc bb cc a1 b1 c1 a2 b2 c2 12 20 30

输出前面两列:NF参数

root@newbie-unknown85880:/tmp# awk '{NF=2;print $0 }' test.txt  abc bb a1 b1 a2 b2 12 20

输出指定某一列,比如第二列,可以将02 ,输出最后一列为 $NF

3.对分隔符的控制

-F 是对文本处理的时候的分隔符,可以指定新的分割符,默认是空格:

root@newbie-unknown85880:/tmp# awk -F'a' '{print $1,$2}' test.txt  bc bb cc 1 b1 c1 2 b2 c2 12 20 30

-Fs 可以这样,也是定义分隔符,但是跟-F不一样的是,他不会把分隔符a给隐藏了:

root@newbie-unknown85880:/tmp# awk '{FS="a";print $1,$2}' test.txt abc bb 1 b1 c1 2 b2 c2 12 20 30

指定分隔符为2 :这里就不会隐藏了,跟-F用法效果一样

root@newbie-unknown85880:/tmp# echo "111|24252|333"|awk 'BEGIN{FS="2"}{print $1,$2}' 111| 4

4.支持运算

原内容如下:

root@newbie-unknown85880:/tmp# cat test2.txt  12 13 15 0 -1 20

求和和求平均示例:

root@newbie-unknown85880:/tmp# awk '{sum=$1+$2+$3;avg=sum/3;print $1,avg,sum}' test2.txt 12 13.3333 40 0 6.33333 19

判断匹配输出:判断第一列 是否大于0 ,大于的才输出

root@newbie-unknown85880:/tmp# awk '$1>0{print $0}' test2.txt  12 13 15

统计字符数:统计每行的字符长度,输出

root@newbie-unknown85880:/tmp# awk '{print length}' test2.txt  10 10 a

注意:会把分隔符长度也统计进去

5.模式匹配

精确匹配:例如匹配第1列为 a1 的

root@newbie-unknown85880:/tmp# awk '$1=="a1"{print $0}' test.txt  a1 b1 c1

模糊匹配:匹配第一列 含有 a 的:

root@newbie-unknown85880:/tmp# awk '$1 ~"a"{print $0}' test.txt  abc bb cc a1 b1 c1 a2 b2 c2

多条件匹配:匹配 第一列含有 a1 且第二列 含有 b1的:

root@newbie-unknown85880:/tmp# awk '/a1/ && /b1/' test.txt a1 b1 c1

注意 && || ! 三个条件的使用,这里不多举例。

6. 支持各种if判断 和for、while循环

awk是一门语言,if和for是最基本的语法之一,这里做一个简单示例: 
if : 判断 第二域是否等于13,等价于前面讲的精确匹配

root@newbie-unknown85880:/tmp# awk '{if($2 =="13")print $0}' test2.txt  12 13 15

for :让所有行循环三次输出:

root@newbie-unknown85880:/tmp# awk '{for(i=1;i<=3;i++)print $0}' test2.txt  12 13 15 12 13 15 12 13 15 0 -1 20 0 -1 20 0 -1 20

while 等价于for的语法

root@newbie-unknown85880:/tmp# awk '{i=1;while(i<=3){print $0;i++}}' test2.txt  12 13 15 12 13 15 12 13 15 0 -1 20 0 -1 20 0 -1 20

7、NR的使用:

NR参数,是awk内置变量之一,在匹配的时候会逐行加1 
删除偶数行:

root@newbie-unknown85880:/tmp# awk 'NR%2!=0{print $0}' test.txt  abc bb cc a2 b2 c2

输出行数:

root@newbie-unknown85880:/tmp# awk '{print NR ,$0}' test.txt  1 abc bb cc 2 a1 b1 c1 3 a2 b2 c2 4 12 20 30

8、RS的使用:

指定行分隔符为 “|”

root@newbie-unknown85880:/tmp# echo "111 222|333 444|555 666"|awk 'BEGIN{RS="|"}{print $0}' 111 222 333 444 555 666

说明:每行的分隔是一个 \n,这里指定分隔符为 “|”的效果是,碰到“|” 将其替换成 \n 。

9、ORS的使用:

将默认分隔“\n”,替换成 “*” :

root@newbie-unknown85880:/tmp# awk 'BEGIN{ORS="*"}{print $0}' test.txt abc bb cc*a1 b1 c1*a2 b2 c2*12 20 30*root@newbie-unknown85880:/tmp# 

ORS容易和RS搞混,从效果上来看,RS是指定一个分隔符,碰到分隔符将其替换成 默认的ORS值“\n” ,也就是回车,而ORS在重新指定的时候,就是将默认的 “\n” 替换成其他的,比如或“|”,那么文本碰到换行符,就不是换行了,而是出现一个 ,接着输出。

10、OFS的使用:

OFS也是对分隔符的指定,但是效果跟FS的效果不一样的是,OFS会将分隔符替换掉,比如默认是空格分隔符的,替换成 “b” 之后,空格没了,变成b :

root@newbie-unknown85880:/tmp# awk 'BEGIN{OFS="b"}{print $1,$2,$3}' test2.txt  12b13b15 0b-1b20

猜你喜欢

转载自www.cnblogs.com/lifei02/p/9892478.html
今日推荐