前言:
最近复习了下 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