awk命令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了awk命令相关的知识,希望对你有一定的参考价值。
1.awk命令awk的设计使得他非常适合处理由行列组成的文本数据。awk还是一种编程语言环境,他提供了正则表达式的匹配,流程控制,运算符,表达式,变量,以及函数等一系列的程序设计语言所具备的特性。
2.awk命令的基本语法
awk命令的基本语法:
awk 匹配模式 { 执行的操作 }
2.1 awk的工作流程
awk处理数据时,他会反复执行一下4个步骤:
1.自动的从数据文件中读取文本的行。
2.自动更新 awk 的内置系统变量的值。例如:列数变量NF,行数变量NR,行变量$0,各个变量$1,$2等。
3.依次执行程序中的所有的匹配模式及其操作。
4.当执行完程序的所有匹配模式和操作后,如果数据文件中仍有未读取的数据行,则返回第一步重复执行1~4的操作。
2.2 awk的执行方式
用户通过3种方式来执行awk程序,分别是命令行,awk脚本,可执行文件。
命令行语法 awk 'awk程序语句' 待处理的文件 。例如:awk '{ print }' a.txt
awk脚本语法 awk -f awk脚本 待处理的文件 。awk脚本里依次写上awk程序语句即可。
可执行脚本语法 awk脚本 待处理的文件 。但是一定要指定命令解释器 #! /bin/awk -f 。脚本内容依次写上awk的程序语句即可。
2.3 特殊字符
$0:表示整个当前行
$1:每行第一个字段
NF:字段数量变量
NR:每行的记录号,多文件记录递增
FNR:与NR类似,不过多文件记录不递增,每个文件都从1开始
FS:BEGIN时定义分隔符,默认是空格或制表符。
RS:输入的记录分隔符,默认是换行符。awk每次读取一行进行处理,通过指定行分隔符,来决定awk一次读取多少行。例如:指定行分隔符为空行,awk每次读取有空格的地方。
\t:制表符
\n:换行符
~ :匹配,与==相比不是精确比较
!~:不匹配,不精确比较
== :等于,必须全部相等,精确比较
!= :不等于,精确比较
&&:逻辑与
||: 逻辑或
+:匹配时表示1个或1个以上
/[0-9][0-9]+/: 两个或两个以上数字
/[0-9][0-9]*/ : 一个或一个以上数字
OFS:输出字段分隔符, 默认也是空格,可以改为制表符等
ORS:输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F ':' :指定分隔符
3.awk的模式匹配
awk的匹配模式主要包括关系表达式,正则表达式,混合模式,BEGIN模式,END模式等。
3.1 关系表达式
awk提供了许多关系运算符,例如大于> ,小于< ,等于==等,awk可以以关系表达式作为匹配模式,当文本行满足关系表达式时,则会执行响应的操作。
实例:
显示第二段大于80的行。
# awk '$2 > 80 { print }' 1.txt
q 90
e 86
r 84
y 98
表示第二列的值大于80,执行花括号里面的 print 操作。
3.2 正则表达式
awk支持正则表达式匹配,和sed一样,需要放在两条斜线 /xx/ 之间。
实例:
# awk '/^(w|r)/ { print }' 1.txt
w 75
r 84
表示匹配w或r 并 print 出来。
3.3 混合模式
awk支持关系表达式和正则表达式,同时支持使用逻辑运算符。
&&:逻辑与
||:逻辑或
!:逻辑非
实例:
# awk '/^w/ && $2 > 70 { print }' 1.txt
w 75
两条匹配模式都为真,才会显示。
# awk '/^w/ || /^r/ { print }' 1.txt
w 75
r 84
两条匹配模式哪条为真显示哪条。都为真都显示。
3.4 区间模式
区间模式是显示两条匹配模式之间的文本行。格式如下:
匹配模式1, 匹配模式2
实例:
匹配root开头的行和UID为3之间的行。-F指定分隔符。
# awk -F ":" '/^root/, $3==3 { print }' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
3.5 BEGIN模式
BEGIN模式是一种内置的模式,该模式里的内容生命周期只会被执行一次,一般用在脚本里面。语法如下:
#! /bin/awk -f
BEGIN {
执行的操作1
执行的操作2
...
}
{ 对待处理的文件执行的操作 }
写成一行就是:
awk 'BEGIN { 执行的操作1; 执行的操作2; } { 对待处理的文件执行的操作 }' 待处理的文件
实例:
只使用BEGIN模式显示内容。
# awk 'BEGIN { print "aaa"; print "=======" }'
aaa
=======
使用BEGIN模式同时文件进行操作。
# awk 'BEGIN { print "aaa"; print "=======" } { print }' 1.txt
aaa
=======
q 90
w 75
e 86
3.6 END模式
END模式也生命周期只会执行一次。一般会把善后的工作放在END模式对应模块里。在执行END模块之前,必须执行操作或者执行BEGIN模式, 语法如下:
#! /bin/awk -f
{ 对待处理的文件执行的操作 }
END {
执行的操作1
执行的操作2
...
}
写成一行就是:
awk ' { 对待处理的文件执行的操作 } END { 执行的操作1; 执行的操作2; }' 待处理的文件
实例:
执行END模式,前面必须有操作,不然不能执行。
# awk '{ print } END { print "aaa"; print "=======" }' 1.txt
q 90
w 75
e 86
aaa
=======
执行BEGIN模式和END模式
# awk 'BEGIN { print "aaa"; print "=======" } END { print "======="; print "aaa" }' 1.txt
aaa
=======
=======
aaa
4. 变量
awk的变量包括自定义的变量和系统内置变量。
4.1 自定义变量和引用
要放在BEGIN模式里面,不然不会执行成功。引用变量直接跟变量名即可。
# awk 'BEGIN { x=3; print x }'
3
4.2 系统内置变量
4.3 内置变量行分隔符FS 字段分隔符RS
awk对文本进行处理是一行一行选取的,然后对文本行进行处理。
因为系统变量FS默认的分隔符是换行符“\n”,如果更改换行符则会每次读取到换行符的位置。
一般把 FS 和 RS 放在BEGIN 模块里面。
实例1:
指定A为分割符,所以在处理后的A都换行符,而不出现了。
ccc下面的空格是文件本身的换行符\n。
# cat 1.txt
aaaAbbbAccc
# awk '{ print } { print "===="}' 1.txt //正常显示
aaaAbbbAccc
====
# awk 'BEGIN { RS="A" } { print }{ print "===="}' 1.txt //指定RS之后
aaa
====
bbb
====
ccc
====
实例2:
把A当做字段分割符,显示第一段,则第一个A前面的内容为第一个字段符。
# cat 1.txt
a a a A b b b A c c c
# awk '{ print $1 }' 1.txt //正常显示
a
# awk 'BEGIN { FS="A" } { print $1 }' 1.txt //指定FS之后。空格不再是分隔符了。
a a a
实例3:
匹配第三段大于500的行,print 第137段,分隔符用#。
# awk -F ":" '$3>500 { print $1"#"$3"#"$7}' test.txt
nfsnobody#4294967294#/sbin/nologin
mysql#501#/sbin/nologin
# awk -F ":" '{OFS="#"}$3>500 { print $1,$3,$7}' test.txt
nfsnobody#4294967294#/sbin/nologin
mysql#501#/sbin/nologin
4.4 记录$0 ,字段$n 的引用
在awk中,用户可以使用系统变量引用记录和字段。
虽然awk每次读取的是一行,但在程序中记录和字段的引用都是针对当前整个文件或数据流来说的。也就是如果要显示第一段会显示整个文件的第一段。
实例1:
变量$0的值就是当前的记录值,可以说是当前文件或者数据流的内容。
# awk '{ print $0 }' 1.txt
wang 85 92 79 87
li 89 90 73 82
zhao 81 88 92 81
实例2:
$1 $2 $3 分别代表第一列 第二列 第三列的数值。可以使用变量把数值的值相加。
# awk '{ print $1, $2+$3+$4+$5}' 1.txt
wang 343
li 334
zhao 342
5.运算符和表达式
5.1 算术运算符
实例:
# awk ' BEGIN { print 3^2 , 5%2 , 5/2 , 2*3 } '
9 1 2.5 6
5.2 赋值运算
实例:
# awk ' BEGIN { print x=5 , x+=5 , x%=6 , x*=3 } '
5 10 4 12
5.3 条件运算符
即当表达式的值为真时,返回数值1,否则返回数值2。语法如下:
变量=(表达式?"数值1":"数值2")
print 变量
实例:
判断打印成绩单中的数值是否大于85,大于90的给A,否则给B。
# awk '{ a=($2>85?"A":"B"); print a }' 1.txt
B
A
B
# awk '{ a=($2>85?"A":"B"); print $1,a }' 1.txt
wang B
li A
zhao B
5.4 逻辑运算符
awk支持3种逻辑运算,分别是逻辑与,逻辑或和逻辑非。
实例:
当所有字段的数值都大于80时,才显示出来。
# awk '$2 > 80 && $3 > 80 && $4 > 80 && $5 > 80 { print } ' 1.txt
zhao 81 88 92 81
5.5 关系运算
awk支持关系运算一般有:大于,小于,等于 等..
匹配运算符~ 不匹配运算符!~是awk特有的关系运算符,语法如下:
字符串 ~ 表达式
字符串 !~ 表达式
匹配运算符:判断字符串中是否包含表达式的字符串。
不匹配运算符:判断字符串中是否不包含表达式的字符串。
实例:
匹配第一个字符l开头的记录。
# awk '$1~/^l/ { print }' 1.txt
li 89 90 73 82
匹配前十行,第一段包含是root或者lp的行
# awk -F ":" 'NR<=10 && $1 ~ /root|lp/' test.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
以上是关于awk命令的主要内容,如果未能解决你的问题,请参考以下文章