一、awk基础语法(常用,其他不常用) 语法:
awk[选项]‘条件{动作}条件{动作}’文件名 ...
1、内置变量
变量名 | 描述 |
---|---|
FILENAME | 当前输入文件的名称 |
FNR | 当前输入文档的当前行号,尤其当有多个输入文档时有用 |
NR | 输入数据流的当前行号 |
$0 | 当前行的全部内容 |
$n | 当前行的第n个字段内容(n>1) |
NF | 当前记录(行)的字段(列)个数 |
FS | 字段分隔符,默认为空格或Tab制表符 |
OFS | 输出字段分隔符,默认为空格 |
ORS | 输出行分隔符,默认换行符为\n |
RS | 输入行分隔符,默认换行符为\n |
[root@www jiaofan]# free | awk '{print $2}'#<==打印第二列
used
995672
2097148
[root@www jiaofan]# free | awk '{print NR}'#<==输出行号
1
2
3
[root@www jiaofan]# free | awk '{print NF}'#<==输出每行的列数
6
7
4
[root@www jiaofan]# free | awk '{print $NF}'#<==打印最后一列
available
287716
2097148
[root@www jiaofan]# free | awk '{print $(NF-1)}'#<==打印倒数第二列
buff/cache
288292
0
[root@www jiaofan]# cat test1.txt#<==文件1
hello world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# cat test2.txt#<==文件2
biscuit:crisp:chichen
salt-jam:oil,suger
banana:lemon,pear--apple:grape
[root@www jiaofan]# awk '{print $2}' test1.txt#<==输出第一列
world!
men
is
[root@www jiaofan]# awk '{print $0}' test1.txt#<==输出每行的全部内容
hello world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# awk '{print}' test1.txt#<==输出每行的全部内容
hello world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# awk '{print NR}' test1.txt test2.txt#<==打印当前行号
1
2
3
4
5
6
[root@www jiaofan]# awk '{print FNR}' test1.txt test2.txt#<==打印当前文件行号
1
2
3
1
2
3
[root@www jiaofan]# awk'{print FILENAME}'test1.txt test2.txt
test1.txt
test1.txt
test1.txt
test2.txt
test2.txt
test2.txt
[root@www jiaofan]#
2、自定义变量(-v)
[root@www jiaofan]# awk -v x="jiaofan"-v y=11'{print x,y}' test1.txt
jiaofan 11
jiaofan 11
jiaofan 11
[root@www jiaofan]# x="hello"
[root@www jiaofan]# awk -v i=$x '{print i}' test1.txt#<==输出变量
hello
hello
hello
[root@www jiaofan]# awk '{print "'$x'"}' test1.txt#<==输出变量
hello
hello
hello
定义分隔符:FS 或 F
[root@www jiaofan]# cat test2.txt
biscuit:crisp:chichen
salt-jam:oil,suger
banana:lemon,pear--apple:grape
[root@www jiaofan]# awk -v FS=":" '{print $1}' test2.txt#<==以:为分隔符
biscuit
salt-jam
banana
[root@www jiaofan]# awk -v FS="[:,-]"'{print $1}' test2.txt#<==以:和-为分隔符
biscuit
salt
banana
[root@www jiaofan]# awk -F":" '{print $1}' test2.txt#<==以:为分隔符
biscuit
salt-jam
banana
[root@www jiaofan]# awk -F"[:,-]"'{print $1}' test2.txt#<==以:和-为分隔符
biscuit
salt
banana
[root@www jiaofan]#
输入行分隔符,默认是\n,可以修改RS自定义分隔符
[root@www jiaofan]# cat test1.txt
hello world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# awk -v RS="," '{print $1}' test1.txt
hello
while
上面以逗号问行分隔符,所以输入内容为两行分别是
hello world!\nother men live to eat
while I eat to live.\nIt is never too late to mend.
输出字段分隔符OFS
[root@www jiaofan]# awk '{print $3,$1,$3}' test1.txt#<==默认是空格为分隔符
hello
live other live
never It never
[root@www jiaofan]# awk -v OFS=":" '{print $3,$1,$3}' test1.txt#<==设置冒号为分隔符
:hello:
live:other:live
never:It:never
[root@www jiaofan]# awk -v OFS="-" '{print $3,$1,$3}' test1.txt
-hello-
live-other-live
never-It-never
[root@www jiaofan]# awk -v OFS="\t" '{print $3,$1,$3}' test1.txt#<==设置制表符为分隔符
hello
live other live
never It never
[root@www jiaofan]# awk -v OFS="." '{print NR,$0}' test1.txt
1.hello world!
2.other men live to eat,while I eat to live.
3.It is never too late to mend.
输出行分隔符ORS
[root@www jiaofan]# cat test1.txt
hello world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# awk -v ORS=":" '{print}'test1.txt
hello world!:other men live to eat,while I eat to live.:It is never too late to mend.:
3、print 指令
[root@www jiaofan]# awk '{print "data:",$1}' test1.txt
data: hello
data: other
data: It
[root@www jiaofan]# awk '{print 12345}' test1.txt
12345
12345
12345
[root@www jiaofan]# awk '{print $1,12345,$3}' test1.txt
hello 12345
other 12345 live
It 12345 never
[root@www jiaofan]# awk '{print "第一列",$1,"\t第二列:",$2}' test1.txt
第一列 hello第二列: world!
第一列 other第二列: men
第一列 It第二列: is
4、条件匹配
比较符号 | 描述 |
---|---|
// | 全行数据正则匹配 |
!// | 对全行数据正则匹配后取反 |
~// | 对特定数据正则匹配 |
!~// | 对特定数据正则匹配后取反 |
== | 等于 |
!= | 不等于 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
&& | 逻辑与,如A&&B,要求满足A并且满足B |
|| | 逻辑或,如A||B,要求满足A或者满足B |
[root@www jiaofan]# cat test1.txt#<==准备素材
hello the world!
other men live to eat,while I eat to live.
It is never too late to mend.
[root@www jiaofan]# awk '/the/'test1.txt#<==每行正则匹配the
hello the world!
other men live to eat,while I eat to live.
[root@www jiaofan]# awk '$2~/the/'test1.txt#<==每行第二列正则匹配the
hello the world!
[root@www jiaofan]# awk '$4==to'test1.txt#<==每行第四列精确匹配the
hello the world!
[root@www jiaofan]# awk -F: '$3>=100' /etc/passwd
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
nisuser1:x:1001:1001::/home/nisuser1:/bin/bash
nisuser2:x:1002:1002::/home/nisuser2:/bin/bash
nisuser3:x:1003:1003::/home/nisuser3:/bin/bash
[root@www jiaofan]# awk 'NR==4' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@www jiaofan]# awk -F: '$3>1 && $3<5' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@www jiaofan]# awk -F: '$3==1 || $3==5' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
[root@www jiaofan]#
awk 的匹配条件可以使BEGIN 或 END(大写字母),BEGIN 会导致动作指令仅在读取任何数据记录之前执行一次,END 会导致动作指令仅在读取完所有数据记录后执行一次。利用 BEGIN 我们可以进行数据的初始化操作,而 END 则可以帮助我们进行数据的汇总操作。
[root@www jiaofan]# awk -F:'BEGIN{print "用户名 UID 解释器"}{print $1,$3,$7}END{print "总计有"NR"个账户。"}'/etc/passwd | column -t
用户名UID解释器
root0/bin/bash
bin1/sbin/nologin
daemon2/sbin/nologin
... ...
总计有25个账户。
[root@www jiaofan]# awk 'BEGIN{print 10-4}'
6
[root@www jiaofan]# awk 'BEGIN{x=8;
y=2;
print x-y}'#<==对变量进行减法
6
在awk中变量不需要定义就可以直接使用,作为字符处理时未定义的变量默认值为空,作为数字处理时未定义的变量默认值为0
[root@www jiaofan]# awk 'BEGIN{print x+8}'
8
[root@www jiaofan]# awk 'BEGIN{print "["x"]","["y"]"}'
[] []
[root@www jiaofan]# who | awk '$1=="root"{x++} END{print x}'
2
[root@www jiaofan]# ls -l /etc/*.conf | awk '{sum+=$5} END{print sum}'
44107
[root@www jiaofan]# ls -l /etc/*.conf | awk '/^-/{sum+=$5} END{print "文件总量:"sum"."}'
文件总量:44107.
[root@www jiaofan]#
二、条件判断 awk单支语句
if(判断条件){
动作指令序列;
}
awk双支语句
if(判断条件){
动作序列1;
}
else{
动作序列2;
}
awk多支语句
if(判断条件1){
动作序列1;
}
else if(判断条件2){
动作序列1;
}
else{
动作序列2;
}
三、awk 数组
一维数组:
数据名[索引]=值
多维数组:
数据名[索引1][索引2]=值
或者
数据名[索引1,索引2]=值
【linux|shell编程--三剑客之awk】for循环读取索引
for(变量 in 数据名){
动作指令序列
}
判断索引是否为数组成员
if (索引 in 数据)
四、awk 循环 for循环
for(表达式1;
表达式2;
表达式3){
动作指令序列
}
while 循环
while(条件判断){
动作指令序列;
}
五、awk 函数 1、内置I/O函数
函数 | 说明 |
---|---|
getline | getline会读取下一条数据,而不会影响后续awk指令的执行 |
next | next不仅读取下一行数据,会导致后续的指令不再执行,而是重新读取数据后重新回到awk指令的开始位置,重新匹配,重新执行动作指令 |
system(“命令”) | awk会启动一个新的shell进程执行命令 |
[root@www jiaofan]# cat test.txt
1:hello the world.
2:go spurs air.
3:123 456 789.
4:hello the beijing.
[root@www jiaofan]# awk '/air/{getline;
print "next line:",NR,$0} {print "noraml line NR="NR}' test.txt
noraml line NR=1
next line: 3 3:123 456 789.
noraml line NR=3
noraml line NR=4
[root@www jiaofan]# awk '/air/{next;
print "next line:",$0} {print "noraml line NR="NR}' test.txt
noraml line NR=1
noraml line NR=3
noraml line NR=4
[root@www jiaofan]# awk 'BEGIN{system("uptime")}'
16:44:45 up6:56,3 users,load average: 0.00, 0.01, 0.05
[root@www jiaofan]# awk 'BEGIN{system("echo jiaofan")}'
jiaofan
2、内置数值函数
函数 | 说明 |
---|---|
cos(expr) | 函数返回expr的cosine值 |
sin(expr) | 函数返回expr的sine值 |
sqrt(expr) | 函数返回expr的平方 |
int(expr) | 函数为取整函数,仅截取整数部分的数值 |
rand() | 函数可以返回0到1之间的随机数N(0<=N<1) |
srand() | 函数可以使用expr定义新的随机数种子,没有expr时则使用当前系统的时间为随机数种子 |
[root@www jiaofan]# awk 'BEGIN{print cos(50)}'
0.964966
[root@www jiaofan]# awk 'BEGIN{print sin(50)}'
-0.262375
[root@www jiaofan]# awk 'BEGIN{print sqrt(2)}'
1.41421
[root@www jiaofan]# awk 'BEGIN{print sqrt(4)}'
2
[root@www jiaofan]# awk 'BEGIN{print int(4.6)}'
4
[root@www jiaofan]# awk 'BEGIN{print rand()}'
0.237788
[root@www jiaofan]# awk 'BEGIN{for(i=1;
i<=5;
i++)print rand()}'
0.237788
0.291066
0.845814
0.152208
0.585537
[root@www jiaofan]# awk 'BEGIN{print 100*rand()}'
23.7788
[root@www jiaofan]# awk 'BEGIN{print rand()}'#<==没有新种子随机数固定
0.237788
[root@www jiaofan]# awk 'BEGIN{srand();
print rand()}'#<==使用时间做随机数
0.217179
[root@www jiaofan]# awk 'BEGIN{srand(897);
print rand()}'#<==使用897做随机数
0.504158
[root@www jiaofan]# awk 'BEGIN{srand(897);
print rand()}'
0.504158
3、内置字符串函数 length([s]) 函数可以统计字符串s的长度,如果不指定字符串 s 则统计$0的长度。
[root@www jiaofan]# awk 'BEGIN{test="hello the world";
print length(test)}'
15
index(字符串1,字符串2) 函数返回字符串2在字符串1中的位置坐标。
[root@www jiaofan]# awk 'BEGIN{test="hello the world";
print index(test,"h")}'#<==h在test变量的第一个位置
1
[root@www jiaofan]# awk 'BEGIN{test="hello the world";
print index(test,"t")}'#<==t在test变量的第一个位置
7
match(s,r) 函数根据正则表达式 r 返回其在字符串s中的位置坐标。
[root@www jiaofan]# awk 'BEGIN{print match("How much? 981$","[0-9]")}'#<==数字在第11个位置出现
11
[root@www jiaofan]# awk 'BEGIN{print match("How 4much? 981$","[0-9]")}'#<==数字在第5个位置出现
5
[root@www jiaofan]# awk 'BEGIN{print match("How much? 981$","[a-z]")}'
2
[root@www jiaofan]# awk 'BEGIN{print match("How much? 981$","[A-Z]")}'
1
tolower(str) 函数可以将字符串转换为小写
[root@www jiaofan]# awk 'BEGIN{apple[0]="red aPPLe";
print tolower(apple[0])}'
red apple
toupper(str) 函数可以将字符串转换为大写。
[root@www jiaofan]# awk 'BEGIN{apple[0]="red aPPLe";
print toupper(apple[0])}'
RED APPLE
split(字符串,数组,分隔符) 函数可以将字符串按特定的分隔符切片后存储在数组中,如果没有指定分隔符,则使用FS定义的分隔符进行字符串分隔。
[root@www jiaofan]# awk 'BEGIN{split("hello the world",test);
print test[1],test[2]}'
hello the
这条命令以空格或Tab键为分隔符,将hello the world 切割为独立的三个部分,分别存入 test[1]、test[2]、test[3] 数组中,最后通过 print 指令可以按照任意顺序打印显示这些数组元素的值。
[root@www jiaofan]# awk 'BEGIN{split("hello:the:world",test);
print test[1] test[2]}'#<==test[2]为空值
hello:the:world
[root@www jiaofan]# awk 'BEGIN{split("hello:the:world",test,":");
print test[1] test[2]}'#<==自定义分隔符为冒号
hellothe
[root@www jiaofan]# awk 'BEGIN{split("hello:the:world",test,":");
print test[1],test[2]}'
hello the
[root@www jiaofan]# awk 'BEGIN{split("hi8the3world4!",test,"[0-9]");
print test[1],test[4]}'#<==使用正则定义分隔符
hi !
[root@www jiaofan]#
gsub(r,s,[,t]) 函数可以将字符串 t 中所有的正则表达式 r 匹配的字符串全部替换为 s ,如果没有指定字符串 t ,默认对$0进行替换操作。
[root@www jiaofan]# awk 'BEGIN{hi="hello world";
gsub("o","O",hi);
print hi}'#<==小写o换成大写O
hellO wOrld
[root@www jiaofan]# head -1 /etc/passwd | awk '{gsub("[0-9]","**");
print $0}'#<==全部的数字替换成**
root:x:**:**:root:/root:/bin/bash
sub(r,s,[,t]) 函数与gsub类似,但仅替换第一个匹配的字符串,而不是替换全部。
[root@www jiaofan]# head -1 /etc/passwd | awk '{sub("[0-9]","**");
print $0}'
root:x:**:0:root:/root:/bin/bash
[root@www jiaofan]# head -1 /etc/passwd | awk '{sub("root","**");
print $0}'
**:x:0:0:root:/root:/bin/bash
substr(s,i[,n]) 函数可以对字符串s 进行截取,从第i位开始,截取n个字符串,如果n没有指定则一直截取到字符串s的末尾位置。
[root@www jiaofan]# awk 'BEGIN{hi="hello world";
print substr(hi,2,3)}'#<==从第2位开始截取3个字符
ell
[root@www jiaofan]# awk 'BEGIN{hi="hello world";
print substr(hi,2)}'#<==从第2位开始截取到末尾
ello world
4、内置时间函数 systime() 返回当前时间距离1970-01-01 00:00:00 有多少秒。
[root@www jiaofan]# awk 'BEGIN{print systime()}'
1646017041
[root@www jiaofan]#
推荐阅读
- linux|shell编程--三剑客之sed
- shell|Linux系统yum安装rz sz命令
- http|Cookie、Session和Token的区别与联系
- 趣学Java|干掉Session(这个跨域认证解决方案真的优雅)
- c语言中point的用法|c语言中point的用法_嵌入式C语言自我修养 01(Linux 内核中的 C 语言语法扩展)
- Springboot+Git+Jenkins+Docker实现CI/CD
- 其他|单点登录的几种方案
- cookie|一文了解Session