- Linux Shell和基本指令
- Bash shell语法
- 正则表达式
- 文本处理之grep
- 文本处理之sed
- 文本处理之awk
- Text GUI编程
- Tomcat启动脚本分析
- gradlew脚本分析
awk是一种处理文本文件的工具,和 sed 命令类似,awk 命令也是逐行扫描并处理的,也就是将寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作。
awk 命令的基本格式为:
$ awk [选项] '脚本命令' 文件名
选项:
F fs 指定以 fs 作为输入行的分隔符,awk 命令默认分隔符为空格或制表符。
-f file 从脚本文件中读取 awk 脚本指令,以取代直接在命令行中输入指令。
-v var=val 在执行处理过程之前,设置一个变量 var,并给其设备初始值为 val。
awk 的强大之处在于脚本命令,它由 2 部分组成,分别为匹配规则和执行命令,如下:
'匹配规则{执行命令}'
匹配规则用来指定脚本命令可以作用到文本内容中的具体行,比如 /abc/,表示处理含有 abc 字符串的行,或者通过正则表达式。
而整个脚本命令是用单引号' '括起,其中的执行命令部分需要用大括号{}括起来。
变量
默认情况下,awk 会将如下变量分配给它在文本行中发现的数据字段:
- $0 代表整个文本行;
- $1 代表文本行中的第 1 个数据字段;
- $2 代表文本行中的第 2 个数据字段;
- $n 代表文本行中的第 n 个数据字段。
这里的数据字段指的是以空格(默认情况)分割的字符,比如一行的数据是ab cd ef ,那么这里就有3个数据字段,分别是ab、cd、ef,在awk中分别以$1、$2、$3代表,这种变量比较常用。
还有其他变量如下所示。
| 变量 | 描述 |
|---|---|
| FS | 字段分隔符 (默认是空格) |
| OFS | 输出字段的分隔符(默认是空格) |
| RS | 行分隔符(默认以\n作为一行的结尾),单行分割成多行用到 |
| NR | 行号,从1开始,多文件时候也是连续接着计数 |
| FNR | 各文件分别计数的行号,多文件的时候会和NR不同,它会重新计数 |
| NF | 一行中字段数量,最后一个字段内容可以用$NF取出 |
| ARGC | 命令行参数的数目 |
| ARGV | 包含命令行参数的数组,第一个参数是命令awk |
示例
打印所有行
$ cat 1.txt
One Text
Two Text
Three Text
$ awk '{print $0}' 1.txt
One Text
Two Text
Three Text
只打印某数据字段
$ awk '{print $1}' 1.txt
One
Two
Three
这里的$1表示每行中以空格分开的第一个数据字段,以此类推,也可以同时指定多个。
$ awk '{print $0,$1,$2}' 1.txt
One Text One Text
Two Text Two Text
Three Text Three Text
匹配指定开头的行
如下使用正则,^1表示处理以1开头的行。
$ cat 1.txt
abc 666
123 777
1234 999
321 333
$ awk '/^1/{print $2}' 1.txt
777
999
统计字段数量
$ awk '{print NF}' 1.txt
2
2
2
2
从date中获取某字段
$ date
2022年 07月 10日 星期日 18:43:37 CST
$ date | awk '{print $5}'
18:44:09
改变输出分割符号
默认输出时候,也是以空格为单位,可以通过OFS="-"指定将以-为单位。
$ date | awk 'OFS="-" {print $4,$5}'
星期日-18:46:59
匹配条件
如下,通过条件判断只显示工资大于1000的人员姓名。
$ cat 1.txt
张三 1200
李四 800
王五 2000
$ awk '$2 > 1000 {print $1}' 1.txt
张三
王五
if else
$ awk '{if (NR % 2==1){print "奇数行 "$1} else {print "偶数行 " $1}}' 1.txt
奇数行 张三
偶数行 李四
奇数行 王五
获取UID大于等于1000的用户
$ awk -F: '$3 >= 1000 {print $1}' /etc/passwd
nobody
hxl
使用内置函数
awk中内置了大量函数,这里就不一一说明.
systime
作用:获取当前时间戳
$ awk 'BEGIN {print systime()}'
substr
作用:截取字符串
$ echo "abcdef" | awk '{print substr($0,0,3)}'
abc
int
作用:转整型,直接省略小数点后面的部分。
$ echo 12.6 |awk '{print int($0)}'
12
rand
作用:随机数
$ echo 12.6 |awk '{print rand()}'
0.767772
BEGIN、END
awk中还有两个关键字BEGIN、END,类似于回调,分别在开始执行时候回调和执行结束后回调。
1. BEGIN{} : 最开始执行
2. {} : 正文
3. END{} : 最后执行
如下
$ awk 'BEGIN {print "开始"} {print $1} END{print "结束"}' 1.txt
开始
张三
李四
王五
结束
获取行号
如现在只想打印奇数行,可以通过内置变量NR获取
$ awk 'NR % 2==1{ print $1}' 1.txt
张三
王五
获取行长度
$ awk 'length($0)>=8 {print "本行长度为:" length($0) " "$0}' 1.txt
本行长度为:8 def 4566
自定义变量
通过-v参数设置一个变量a,值为100,在打印时候将数据段2分别在加上变量a。
$ cat 1.txt
abc 12
def 45
$ awk -va=100 '{print $2+a}' 1.txt
112
145
查看tcp状态为ESTABLISHED的所有连接
$ netstat -an | awk ' BEGIN {print "本地 远程" } $1=="tcp" && $6=="ESTABLISHED"{print $4 " " $5} END {}'
获取所有java进程的id
$ ps -ef |grep java | awk '{print $2}'
23763
24328
统计当前目录文件所有大小
$ ls -l | awk -vsum=0 'BEGIN {} {sum+=$5} END{print sum/1024/1024"MB"}'