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.txt1: biscuit:crisp:ckicken2: salt-jam::iol,sugar3: 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
