标签:逻辑 有用 第一个 自己的 执行 3.3 处理 || while循环
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
awk可以通过命令行方式执行,其实还可以写成脚本的方式跑。
root@newbie-unknown85880:/tmp# awk ‘{print $0}‘ test.txt
abc bb cc
a1 b1 c1
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脚本文件名 被处理文件名
一般文本有很多列,我们要对其实现部分列的输出有:
全部输出:
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
输出指定某一列,比如第二列,可以将0改为2 ,输出最后一列为 $NF
-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
原内容如下:
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
注意:会把分隔符长度也统计进去
精确匹配:例如匹配第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
注意 && || ! 三个条件的使用,这里不多举例。
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
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
指定行分隔符为 “|”
root@newbie-unknown85880:/tmp# echo "111 222|333 444|555 666"|awk ‘BEGIN{RS="|"}{print $0}‘
111 222
333 444
555 666
说明:每行的分隔是一个 \n,这里指定分隔符为 “|”的效果是,碰到“|” 将其替换成 \n 。
将默认分隔“\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” 替换成其他的,比如或“|”,那么文本碰到换行符,就不是换行了,而是出现一个 ,接着输出。
OFS也是对分隔符的指定,但是效果跟FS的效果不一样的是,OFS会将分隔符替换掉,比如默认是空格分隔符的,替换成 “b” 之后,空格没了,变成b :
root@newbie-unknown85880:/tmp# awk ‘BEGIN{OFS="b"}{print $1,$2,$3}‘ test2.txt
12b13b15
0b-1b20
标签:逻辑 有用 第一个 自己的 执行 3.3 处理 || while循环
原文地址:https://www.cnblogs.com/lifei02/p/9892478.html