- 选项
- 变量
- 模式
- 处理
- 操作
- 条件声明
- I/O声明
- 函数
功能
pattern scanning and processing language. awk is a line-oriented language. The pattern comes first, and then the action.
选项
-F ":" # input时分割符,默认空格
-v VAR=val # 给变量赋初始值
-d file # 全局变量打印到文件
变量
- Records 记录,RS分割的文件后的内容为记录
- Fields 字段,F分割Record的内容后为字段
# var
$0 # 所有Fields
$1,$n # 分割Fields后的第1~n字段
RS # 默认输入记录分割符为换行
ORS # 默认输出记录分隔符为换行
NF # 每个record有多少个Field字段
NR # 第几个records
OFS # 输出连接符,默认空格
# example
# 多行替换为一行: 设置变量RS为文件结束,因此只有一个record,在换行符替换为空格
awk -v RS=EOF '{ gsub(/\n/," "); print }' 1.txt
cat 1.txt | xargs echo
# 设置倒数第二个字段为空
awk '{$(NF-1)=" "; print $0}' tmp.sh
# 输出连接符为-,最后字段替换为hi
awk '{OFS="-"; $NF="hi"; print $0}' tmp.sh
模式
先patterns后action
# pattern
BEGIN # 在任何input之前执行
END # 在所有input之后执行
BEGINFILE
ENDFILE
/regular expression/ # 处理each input record
relational expression
pattern && pattern
pattern || pattern
pattern ? pattern : pattern
(pattern)
! pattern
pattern1, pattern2
处理
# action
{} # 大括号括起来
操作
# Operators
(...) Grouping
$ Field reference.
++ -- Increment and decrement
| |& Piped I/O for getline, print, printf.
in Array membership.
条件声明
# Control Statements
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (var in array) statement
for (expr1; expr2; expr3) statement
break
continue
# example
# 统计tcp各状态个数
netstat -nt | awk '{t[$NF]++}END{ for(i in t) print i,t[i] }'
# 计算es中某类索引的每天日志量大小
curl -s http://127.0.0.1:9200/_cat/indices |
awk '{print $3,$(NF-1)}' | grep ^tel | grep `date +%Y.%m.%d` |
awk '{
if($NF~/kb/) { gsub(/kb/,//,$NF);kb += $NF }
else if($NF~/mb/) { gsub(/mb/,//,$NF); mb += $NF }
else if($NF~/gb/) { gsub(/gb/,//,$NF) ; gb += $NF }
}
END {
sum=(kb/1024/1024+mb/1024+gb); printf ("%.2fG\n",sum)
}'
I/O声明
# I/O Statements
getline Set $0 from next input record; set NF, NR, FNR.
getline <file Set $0 from next record of file; set NF.
getline var Set var from next input record; set NR, FNR.
getline var <file Set var from next record of file.
command | getline [var] Run command piping the output either into $0 or var, as above.
next Stop processing the current input record.
print Print the current record.
print ... >> file Appends output to the file.
# example
# 打印文件偶数行内容
awk '{ getline; print $0}' tmp.sh
# 每行前部分增日期信息:执行命令存入变量
awk 'BEGIN{"date"| getline today } {print today,$0}' tmp.sh
2020年 01月 21日 星期二 14:59:05 CST happy new year
# 扫描IP:执行系统命令
tail -f access_log | awk '/myhome.html/ { system("nmap " $1 ">> logdir/myhome.html") }'
函数
# String Functions
substr(s, i [, n]) # 源s,i起始位置 ; 从第i位截取s
gsub(r, s [, t]) # 正则r,目标s, 源t 默认t是$0 ;替换源s中正则r配到的为模板s
match(s, r [, a]) # 源字段s, 正则r, 匹配后存入数组a
# example
# 计算1分钟内网卡速率
a=`ifconfig em1 | awk '/RX bytes/ {print substr($2,7)}'` && sleep 60 && a1=`ifconfig em1 | awk '/RX bytes/ {print substr($2,7)}'` && echo "($a1-$a)/60" | bc
# 替换第二字段hot为hi
awk '{ gsub(/hot/,"hi",$2); print $0}' tmp.sh
# 打印匹配第二字端elk后面的内容
awk '{ match($2,"elk(.*)",a); print a[1] }' tmp.sh
# 统计平均数
# cat 1.txt
a 1
a 2
a 3
a 4
a 5
b 1
b 5
d 9
d 0
cat 1.txt | awk '{ arr[$1]=arr[$1]+$2; num[$1]++ } END{ print "key\tavg"; for(i in arr) print i"\t"arr[i]/num[i] }'
key avg
a 3
b 3
d 4.5
网友评论