3

前言:
最近复习了下awk,记录方便下次查阅

echo '11 22' | awk '{print $1}'
echo |awk '{print "hello world!"}'

一.awk变量

内置常用变量

$0      当前记录,当前行所有列
$1~$n   当前记录的第n个字段,字段间由FS分隔
FS      输入域分隔符,等价于命令行-F,默认为空格
NF      当前记录中的字段个数,就是有多少列,列总数,$NF则表示最后一列
NR      已经读取的记录数,就是第几行,从1开始
FNR     当前记录数
RS    控制记录分隔符,默认为换行符
OFS   输出字段分隔符 默认也是空格
ARGC  命令行参数个数
ARGV  命令行参数排列
FILENAME awk浏览的文件名

自定义变量类型

echo |awk 'i="hello world"{print i}'
echo |awk 'i=1122 {print i}'

数组

echo |awk '{a[1]="hello";a[2]="world!";print a[1],a[2]}'

二.awk常用逻辑运算

?           条件表达操作符
|| && !     并、与、非
~  !~       匹配操作符,包括匹配 不匹配
\+ - * / % ^ 算术操作符
++ --        前缀和后缀
= += *= / = %= ^ =  赋值操作符 
< <= == != >= >     关系操作符     
BEGIN  在输出界面第一行输出相关
END    在输出界面最后一行输出相关

三.awk条件判断

1.直接在最外层

echo '11 22' |awk '$1==11{print $2}'

2.使用if语句

```echo '11 22' |awk '{if($1==11) print $2}'```

3.与或非

与
echo '11 22' |awk '{if(($1==11) && ($2==22))  print $2}'
或
echo '11 22' |awk '{if(($1==10) || ($2==22))  print $2}'
非
echo '11 22' |awk '{if($1!=10)  print $2}'

4.匹配

 ~      模糊匹配
 ==     精确匹配
 !~     不匹配
echo 'ansible new switf' |awk '{if($1 ~ i)  print $1}'
echo 'ansible new switf' |awk '{if($1 !~ 0)  print $1}'

5.正则匹配

last |awk '/root/{print $0}'
last |awk '/roo*/{print $0}'
last |awk '/^root /{print $0}'

四.awk循环

for(i=1;i<=10;i++)
类似C等语言的循环
使用awk将每行插入一个符号"|"和tab建

last |awk '{for(i=1;i<=NF;i++){printf $i "|\t"} print ""}'

NF 每一行所拥有的总字段数

for(i in 数组)
类似shell

echo|awk 'BEGIN{a[1]=1;a[2]=2}END{for(i in a) print i,a[i]}'

五.常用内置函数

gsub(r,s)          在整个$0中用s替代r,相当于 sed 's///g'
gsub(r,s,t)        在整个t中用s替代r
index(s,t)         返回s中字符串t的第一位置
length(s)          返回s长度
match(s,r)         测试s是否包含匹配r的字符串
split(s,a,fs)      在fs上将s分成序列a 
sprint(fmt,exp)    返回经fmt格式化后的exp
sub(r,s)           用$0中最左边最长的子串代替s,相当于 sed 's///'
substr(s,p)        返回字符串s中从p开始的后缀部分
substr(s,p,n)      返回字符串s中从p开始长度为n的后缀部分

六.运维常用的awk

1.打印指定倒数字段数
利用NF打印倒数字段,比如打印倒数第2行

last |awk '{print $(NF-1)}'

2.打印文件第1000行到2000行

awk '1000<=FNR && FNR <=2000' file
awk '{if(1000<=FNR && FNR<=2000) print $0}' file

3.使用for循环、数组、自加对netstat的tcp状态统计

netstat -an |awk '/^tcp/ BEGIN{s[$NF]++} END{for(a in s) print a,s[a]}'

4.替换

eg: test.txt

zhangsan 70 99 88 77 good
lisi 90 77 66 88 good
sansan 80 88 78 89 good
awk '{if($2>=90) gsub($NF,"Very Good")} {print $0}' test.txt
zhangsan 70 99 88 77 good
lisi 90 77 66 88 Very Good
sansan 80 88 78 89 good

青叶
452 声望43 粉丝