awk是一个强大的Linux命令,有强大的文本格式化的能力,好比将一些文本数据格式化成专业的excel表的样式
awk早期在Unix上实现,我们用的awk是gawk,是GUN awk的意思
awk更是一门编程语言,支持条件判断、数组、循环等功能
再谈三剑客
- grep,擅长单纯的查找和匹配文本内容
- awk,更适合编辑,处理匹配到的文本内容
- sed,更适合格式化文本内容,对文本进行复杂处理
awk基础
awk语法:
awk [option] 'pattern[action]' file ...
awk 参数 '条件动作' 文件
Action指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此最常用的动作就是print和printf
awk场景
[root@timy-test-k8s01 ~]# cat alex.txt alex1 alex2 alex3 alex4 alex5 alex6 alex7 alex8 alex9 [root@timy-test-k8s01 ~]# awk '{print $2}' alex.txt alex2 alex5 alex8 [root@timy-test-k8s01 ~]#
执行命令awk '{print $2}',没有使用参数和模式,$2表示输出文本的第二列信息
awk默认以空格为分隔符,且多个空格也识别为一个空格,作为分隔符
awk是按行处理文件,一行处理完毕,处理下一行,根据用户指定的分割符去工作,没有指定则默认空格符
- $0表示整行
- $NF表示当前分割后的最后一列
- 倒数第二列可以写成$(NF-1)
awk内置变量
内置变量 | 解释 |
---|---|
$n | 指定分隔符后,当前记录的第n个字段 |
$0 | 完整的输入记录 |
FS | 字段分隔符,默认是空格 |
NF(Number of fields) | 分割后,当前行一共有多少个字段 |
NR(Number of records) | 当前记录数,行数 |
更多内置变量可以man手册查看 | man awk |
一次性输出多列信息
[root@timy-test-k8s01 ~]# awk '{print $1, $2}' alex.txt alex1 alex2 alex4 alex5 alex7 alex8
自定义输出内容
awk,必须外层单引号,内层双引号
内置变量$1、$2都不得添加双引号,否则会识别为文本,尽量别加引号
[root@timy-test-k8s01 ~]# awk '{print "n1:" $1,"n2:" $2}' alex.txt n1:alex1 n2:alex2 n1:alex4 n2:alex5 n1:alex7 n2:alex8
awk参数
参数 | 解释 |
---|---|
-F | 指定分割字段符 |
-v | 定义或修改一个awk内部的变量 |
-f | 从脚本文件中读取awk命令 |
显示文件第N行
#NR在awk中表示行号,NR==3表示行号是3的那一行
#注意一个等于号,是修改变量值的意思,两个等于号是关系运算符,是“等于”的意思
[root@timy-test-k8s01 ~]# awk 'NR==3{print $0}' alex.txt alex7 alex8 alex9
显示行号
[root@timy-test-k8s01 ~]# awk 'NR==3{print NR, $0}' alex.txt 3 alex7 alex8 alex9
awk的分隔符
- 输入分隔符,awk默认是空格,空白字符,英文是field separator,变量名是FS
- 输出分隔符,output field separator,简称OFS
FS输入分割符
awk逐行处理文本的时候,以输入分隔符为准,把文本切成多个片段,默认符号是空格
当我们处理特殊文件,没有空格的时候,可以自由自定分隔符特点。
除了使用-F选项,还可以使用变量的形式,指定分隔符,使用-v选项搭配,修改FS变量
OFS输出分割符
awk执行完命令,默认用空格隔开每一列,这个空格就是awk的默认输出符。
案例
打印网卡IP
[root@timy-test-k8s01 ~]# ifconfig ens192 ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.16.66.88 netmask 255.255.255.0 broadcast 10.16.66.255 inet6 fe80::2834:95d6:baaa:9918 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:d1:81:3e txqueuelen 1000 (Ethernet) RX packets 13270741 bytes 859786511 (819.9 MiB) RX errors 0 dropped 305 overruns 0 frame 0 TX packets 81395 bytes 6677424 (6.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@timy-test-k8s01 ~]# ifconfig ens192 | awk 'NR==2{print $0}' inet 10.16.66.88 netmask 255.255.255.0 broadcast 10.16.66.255 [root@timy-test-k8s01 ~]# ifconfig ens192 | awk 'NR==2{print $2}' #打印第二行第二列就得到了IP地址 10.16.66.88
对于awk而言,变量分为
- 内置变量
- 自定义变量
内置变量 | 解释 |
---|---|
FS | 输入字段分隔符,默认为空白字符 |
OFS | 输出字段符,默认为空白字符 |
RS | 输入记录分割符(输入换行符),指定输入时的换行符 |
ORS | 输出记录分隔符(输出换行符),输出时指定符号代替换行符 |
NF | NF:number of field,当前行的字段个数(即当前行被分割成了几列),字段数量 |
NR | NR:行号,当前处理的文本行的行号 |
FNR | FNR:各文件分别计数的行号 |
FILENAME | FILENAME:当前文件名 |
ARGC | ARGC:命令行参数的个数 |
ARGV | ARGV:数组,保存的是明航所给定的各参数 |
内置变量
NR,NF,FNR
- awk的内置变量NR,NF是不用添加$符号的
- 而$0 $1 $2 $3 ... 是需要添加$符号的
ARGC、ARGV
ARGV表示的是一个数组,数组中保存的是命令行所给的参数
数组是一种数据类型,如同一个盒子
盒子有它的名字,且内部有N个小格子,标号从0开始
自定义变量
顾名思义,使我们自定义变量
- 方法一,-v varName=value
[root@timy-test-k8s01 ~]# awk -v myname="timy" 'BEGIN{print "my name is?"}' #自定义变量myname my name is? [root@timy-test-k8s01 ~]# awk -v myname="timy" 'BEGIN{print "my name is?", myname}' #使用自定义变量myname my name is? timy
- 方法二,在程序中直接定义