awk 文本分析工具#
说明:
awk
是一种编程语言,用于在 linux/uniⅸ 下对文本和数据进行处理。数据可以来自标准输入 (stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是 linux/unix 下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk
有很多内置的功能,比如数组、函数等,这是它和 C 语言的相同之处,灵活性是awk
最大的优势。
语法:
awk [option] 'PATTERN{ACTION STATEMENTS}' FILE
awk 执行过程#
awk 程序结构#
结构 | 解释 |
---|---|
BEGIN{ awk-commands } | 可省略,里面的内容在 awk 读取文件之前执行 |
/pattern/{ awk-commands } | 可省略,对于输入的每一行,都会执行一次该部分代码,可以添加 /parttern/ 对输入行进行过滤 |
END{ awk-commands } | 可省略,里面的内容在 awk 读取文件完毕之后执行 |
示例#
# 准备如下文本内容
[root@localhost ~]# cat emp.txt
001 张三 1000 10
002 李四 2000 10
003 王五 3000 10
004 赵六 2000 20
005 小红 1800 30
006 小丽 800 20
# 用awk命令输出文本内容
[root@localhost ~]# awk '{print}' emp.txt
# 输出文本内容,添加表头和表的结尾(-------------------)
[root@localhost ~]# awk 'BEGIN{print "编号 姓名 工资 部门"}{print}END{print "-------------------"}' emp.txt
编号 姓名 工资 部门
001 张三 1000 10
002 李四 2000 10
003 王五 3000 10
004 赵六 2000 20
005 小红 1800 30
006 小丽 800 20
-------------------
awk 命令选项#
选项 | 含义 |
---|---|
-F fs | 指定输入文件分隔符(默认是空白字符),fs 是一个字符串或者是一个正则表达式 |
-v var=value | 赋值一个用户定义变量 |
-f scriptfile | 从脚本文件中读取 awk 命令 |
awk 使用方式:
- 命令行使用
直接在命令行里执行
awk
命令
awk '{print}' emp.txt
- awk 脚本使用
将 awk 代码写在文件里(一般以.awk 为文件扩展名), 通过 -f 选项执行
awk -f file.awk emp.txt
- shell 脚本使用
将 awk 命令写到 shell 脚本里,执行 shell 脚本
awk 模式和操作#
模式 | 含义 |
---|---|
/pattern/ | 正则表达式 |
关系表达式 | 使用运算符进行操作 |
模式匹配表达式 | ~ (匹配) !~ (不匹配) |
操作可以由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开
awk 正则范围:
/start/,/end/
NR==1,NR==5
从第 1 行开始第 5 行结束
示例#
# 输出emp.txt包含'小'字的行
[root@localhost ~]# awk '/小/' emp.txt
# 输出从包含'张'的行开始到包含'赵'的行结束
[root@localhost ~]# awk '/张/,/赵/' emp.txt
# 输出前三行
[root@localhost ~]# awk 'NR<=3' emp.txt
[root@localhost ~]# awk 'NR==1,NR==3' emp.txt
[root@localhost ~]# awk 'NR>=1 && NR<=3' emp.txt
# 模式匹配则输出
[root@localhost ~]# awk '666 ~ /[0-9]+/' emp.txt
当使用模式后,如果只是输出行,
awk
语句部分可省略
awk 变量#
内置变量(预定义变量)#
变量 | 含义 |
---|---|
$0 | 执行过程中当前行的内容 |
$n | 当前记录的第 n 个字段(分割后的第 n 列) |
NF | 当前行的字段数,$NF 表示一行中最后一个字段 |
NR | 当前行的行号 |
FS | 输入字段分隔符(默认是空白字符,可使用 - v 指定) |
OFS | 输出字段分隔符(默认是一个空格,可使用 - v 指定) |
RS | 输入记录分隔符(默认是一个换行符,可使用 - v 指定) |
ORS | 输出记录分隔符(默认是一个换行符,可使用 - v 指定) |
FILENAME | 当前文件的文件名 |
自定义变量#
- 使用 - v 选项定义
-v var=value
- 在
awk
程序中定义
awk 'BEGIN{var=value}'
传递外部变量#
-
使用
-v
选项可以给awk
命令传递一个外部变量 -
在命令最后使用
var=value
也可以传递一个外部变量
示例#
# 打印emp.txt每一行的内容、行号和字段数
[root@localhost ~]# awk '{print $0,NR,NF}' emp.txt
# 打印第1列、最后一列和倒数的2列的内容
[root@localhost ~]# awk '{print $1,$NF,$(NF-1)}' emp.txt
# 将文本内容按照 "部门 编号 姓名 工资" 的顺序输出
[root@localhost ~]# awk '{print $4,$1,$2,$3}' emp.txt
# 输出第3行的第2个字段
[root@localhost ~]# awk 'NR==3{print $2}' emp.txt
# 统计每个部门的人数
[root@localhost ~]# awk '{print $NF}' emp.txt | uniq -c
# 将输出字段分隔符修改为':' 并把输出结果写入emp.txt.bak文件
[root@localhost ~]# awk -v OFS=":" '{print $1,$2,$3,$4}' emp.txt > emp.bak.txt
[root@localhost ~]# awk -v OFS=":" 'NF=NF' emp.txt > emp.bak.txt
# 针对emp.txt.bak文件每一行数据,输出: "编号:xxx,姓名:xxx,工资:xxx"
[root@localhost ~]# awk -F: '{print "编号:"$1",姓名:"$2",工资:"$3}' emp.bak.txt
# 自定义变量
# 方式一
[root@localhost ~]# echo | awk -v a=100 '{print a}'
# 方式二
[root@localhost ~]# echo | awk 'BEGIN{b=100;print b}'
# 传递外部变量
[root@localhost ~]# a='aaa'
[root@localhost ~]# b='bbb'
# 方式一
[root@localhost ~]# echo | awk -v v1=$a -v v2=$b '{print v1,v2}'
# 方式二
[root@localhost ~]# echo | awk '{print v1,v2}' v1=$a v2=$b
awk
中
- 要使OFS
变量生效,必须对字段进行操作(可以设置NF=NF
,NF+=0
,$1=$1
...)
格式化打印(printf)#
- 使用方式和 C 语言的
printf
一样 print
显示结果时以逗号分隔,结果会自动将这些内容用分隔符进行分隔,并且不需要添加换行符;printf
可以控制某一个字段的输出格式,需要手动添加换行符
常用格式替换符:
符号 | 解释 |
---|---|
%s | 字符串 |
%f | 浮点数 |
%d | 十进制整数 |
%c | ASCII 字符 |
%% | % 本身 |
常用转义字符:
符号 | 解释 |
---|---|
\n | 换行 |
\t | 水平制表符 |
\v | 垂直制表符 |
\r | 回车 |
\b | 后退 |
\f | 换页 |
\a | 警告字符 |
\\ | \ 本身 |