awk 使用示例
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk 脚本基本结构
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块 3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被放置在 单引号 中
awk 的工作原理
- 执行
BEGIN{ commands }语句块中的语句; - 从文件或标准输入(stdin)读取一行,然后执行
pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。 - 当读至输入流末尾时,执行
END{ commands }语句块。
BEGIN语句块 在awk开始从输入流中读取行 之前 被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块 在awk从输入流中读取完所有的行 之后 即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。
pattern语句块 中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行 { print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。
awk 内置变量(预定义变量)
| 变量 | 说明 | 示例 |
|---|---|---|
| $0 | 当前行的整行内容 | '{print $0}' 打印出当前处理行的整行内容 |
| $n | 当前记录(行)的第n个字段 | '{print $1}' 打印出当前行的第1个字段 |
| NR | 当前处理行的行号(第多少行) | '{print NR,$1}' END{print NR} 打印出当前处理行的行号和第1列,最后打印出总的行号 |
| FNR | 当前处理行在当前处理文件中的行号,只有1个输入文件时,NR=FNR | |
| NF | 当前行的字段数 | '{print NF,$NF,$(NF-1)}' 输出当前行的字段数,最后一个字段 ,倒数第2个字段 |
| FILENAME | 当前输入文件的文件名,-表示stdin |
'{print FILENAME,FNR}' 打印当前处理的文件名及当前行号 |
| FS | 输入字段分隔符,等同于选项 -F ,默认为空格 |
|
| OFS | 输出字段的分隔符,默认为空格 | 'BEGIN{OFS="|"} {print FILENAME,FS,NR,NF,$2,$NF}' 输出结果将会以 | 分割 |
| RS | 输入记录分隔符(行分隔符),默认为换行 | |
| ORS | 输出记录分隔符(行分隔符),默认为换行 |
awk 常用选项
| 选项 | 说明 | 示例 |
|---|---|---|
-F"sep"-F"[,.]" |
等同于内置变量 FS,有2种格式:-F"sep" 使用 sep 整体作为字段分隔符-F[,.] []其中的每个字符都可以作为分隔符等同于 BEGIN预定义变量FS |
|
-v var=1 |
传递用户自定义变量给awk | awk -va=1 -vb=2 '{print a+b}' |
awk 常用运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
| = += -= *= /= %= ^= **= |
赋值 | |
~!~ |
匹配正则表达式 不匹配正则表达式 |
awk '$2 ~ /th/ {print $2,$4}' log.txt 第2列中包含’th’,则输出第2,4列awk 'BEGIN{IGNORECASE=1} /this/' log.txt 忽略大小写匹配 awk '$2 !~ /th/ {print $2,$4}' log.txt 不匹配正则表达式 |
| < <= > >= != == |
关系运算符 | awk '$1>2' log.txt 第1列的值大于2,输出整行awk '$1==2 {print $1,$3}' log.txt 第1列的值等于2,则输出第1,3列 |
| + - * / % |
加,减,乘,除与求余 | |
| + - ! |
一元加,减和逻辑非 | |
| | | | 逻辑或 | |
| && | 逻辑与 | awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt 第1列大于2,并且第2列等于”Are”,则输出第1,2,3列 |
awk 常用用法示例
每一行中第个字段值累加
seq 1 10 | awk 'BEGIN{sum=0;print "第1列求和"}{sum+=$1}END{print "sum="sum}' |
第1列求和
sum=55
判断2列的内容是否相同
awk '{if($1==$2){print $1}}' |
找出字段数(列数)大于3的行
awk 'NF>3{print $0}' |