乐趣区

linux-awk命令常用用法

前言:
最近复习了下 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
退出移动版