date: 2020-09-20title: awk详解 #标题
tags: awk #标签
categories: linux大杂烩 # 分类
这么久以来,貌似从不敢说完全掌握了awk这个工具,又没什么耐心去好好研究此工具,对于awk的使用,一直停留在简单的列过滤,可好好想想,作为shell脚本的三剑客之一的一个工具,还是耐着性子好好整理一下其语法吧。
awk常用内置变量
变量名 | 描述 |
---|---|
FILENAME | 当前输入文档的名字 |
FNR | 当前输入文档的当前行号,尤其当有多个输入文档时有用 |
NR | 输入数据流的当前行号 |
$0 | 当前行的所有内容 |
$n… | n大于0,表示当前行的第n个字段的内容 |
NF | 当前行的字段(列)的个数 |
FS | 字段分隔符,通常使用-F选项代替 |
OFS | 输出字段分隔符,默认为空格 |
ORS | 输出记录分隔符,默认为换行符\n |
RS | 输入记录分隔符,默认为换行符\n |
NR
# 输出行号
$ free | awk '{print NR}'
NF
# 输出每行的总列数
$ free | awk '{print NF}'
# 输出每行的倒数第二列
$ free | awk '{print $(NF-1)}'
# 输出每行的倒数第三列
$ free | awk '{print $(NF-2)}'
$0
# 打印每行的所有列
$ free | awk '{print}'
# 亦可以使用如下指令
$ free | awk '{print $0}'
FS
# 以冒号、逗号或横线进行分隔,然后输出第二列
$ awk -F[:,-] '{print $2}' test.txt
# 注: 在[ ] 的集合中的横线,放在中间就表示范围区间,比如[a-z]
# 所以当我们需要普通字符-时,就需要将其放在开头或末尾,如[-abc]或[abc-]
RS
# 匹配逗号,一个逗号为一行。而不是默认的换行符就是一行
$ awk -v RS="," '{print}' test.txt
OFS
# 输出内容时,每一列都以“-”号分隔(默认为空格)
$ awk -F: -v OFS="-" '{print $2,$1,$2}' test.txt
自定义变量
# 定义x变量并输出x变量值及文件中第一列的值。
$ awk -v x="zhangsan" '{print x,$1}' test.txt
# 定义多个变量
$ awk -v x="zhangsan" -v y=11 '{print y,x,$1}' test.txt
# 输出时,打印行号(默认初始值为0,所以自定义初始值为1)
$ awk -v y=1 '{print y++ ": " $1}' test.txt
1: biscuit:crisp:ckicken
2: salt-jam::iol,sugar
3: banana:lemon,pear--apple:grape
调用系统变量
# 通过 -v 调用
$ x='hello'
$ awk -v y=$x '{print y}' test.txt
# 通过组合多个引号调用
$ x='hello'
$ awk '{print "'$x'"}' test.txt
$ awk -F: -v i=1 '{print "第" i "行第1列为: " $1,"\t第" i "行第2列为: " $2 i++}' test.txt
第1行第1列为: biscuit 第1行第2列为: crisp1
第2行第1列为: salt-jam 第2行第2列为: 2
第3行第1列为: banana 第3行第2列为: lemon,pear--apple3
awk实现数学运算
# 基础运算:
$ echo '10 3' | awk '{print $1/$2}'
3.33333
$ echo '10 3' | awk '{print $1 * $2}'
30
# 变量
$ a=10
$ b=3
$ echo | awk "{print $a/$b}" # 注意此处必须是双引号
3.33333
# 指定小数位数:
$ echo $a $b | awk '{printf "%.2f\n", $1/$2}' # 保留两位小数
3.33