1. 什么是AWK?
AWK是一个强大的格式化文本处理工具,一般在类Unix操作系统中都是必带的工具(Linux、Mac OS),因此,使用无需安装,非常的方便与便捷。
AWK其实是一种类似于shell的脚本编程语言,它支持基本的循环、遍历、判断等基本的功能,因此,你也可以像写shell脚本一样写AWK脚本,AWK也可以被理解为是一种脚本语言的解释器。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。为了掌握AWK的使用,必须掌握一些基本的AWK操作的语法。
2. 为什么学习AWK?
AWK与Grep、Sed并称为linux中的“三剑客”!
三剑客的特点:
grep:适合用于单纯的查找与匹配。
sed:适用于编辑匹配的文本。
AWK:适合处理格式化的文本,对文本进行复杂的格式化处理。
你可能会问:平常我一般会用python处理格式化文本啊,为啥还学AWK?
Maybe,针对一些大的txt文档,两者的执行效率不在一个数量级上….
我认为AWK工具,针对较大的格式化文本数据,可能是介于pandas(便捷)与Spark(高效大数据处理能力)之间的选择,兼顾便捷与效率!
一般AWK的效率优于Python还不想学~那就现实一点而!
曾经亲身参与京东NLP算法实习生面试、百度NLP算法实习生面试,技术面试官直接问:有没有AWK的使用经验…
JD算法工程师招聘所以,面试官的需求就是求职者的最高追求目标!程序猿,这需求还是得尽量满足…搞起!
3.AWK的基本语法:
一条完整的AWK命令由一下几部分构成:
awk [options] 'Pattern{Action}' file
- awk :是AWK命令执行的关键字
- [options]: 是运行的一些参数项,可以省略。
- 'Pattern{Action}': 是命令主要部分,其中Action是核心操作,Parttern有时可以省略。
- file: 用于指定我们操作的格式化文本的名字,可以同时操作多个文件。
3.1 简单介绍{Action}部分
按照编程语言学习的惯例,先来一个AWK界的Hello Word程序:
我们就从使用一个{Action}操作开始,指定一个打印的操作:
AWK输出文本中的内容awk '{print}' a.txt
下面我们进行一个具有实际使用价值的命令:
df命令如果我们只想打印第2列的数据:
AWK输出指定列的内容AWK是逐行处理格式化文本数据的,逐行的意思是,当AWK处理一个文本的时候,会一行一行的处理,处理完第一行再处理下一行,AWK默认是以换行符(回车键/ \n)标记一行的结束,新的一行的开始。
当我们不指定文本内容的分割符的时候,awk默认把每一行的文本内容按照空格进行划分为列(当存在多个连续的空格时当做一个分割)。
注意:AWK的第一列是从下标1开始指定的,$1代表当前行的第1个列数据,而$0是内置的变量,表示整行的内容.
我们构建一个格式化的txt文本,内容如下:
文本内容我们可以输出文本的第一列、第二列数据:
AWK输出指定列内容针对某些列存在字段的缺失,AWK并不会报错,而是输出空值。
我们可以给每一行的数据添加上一些字符串信息到制定的位置:
AWK添加字符串输出awk '{print "IP统计>",$1,"数量:", $3}' test.txt
可知,在{Action}字段内,使用双引号包裹的信息,会被当做字符串输出。
AWK添加字符串输出3.2 简单介绍Pattern部分
前面我们只是简单的介绍了{Action},下面我们简单的了解一下Pattern,也就是模式。这里我先绍两个些比较特殊的模式:BEGIN与END
BEGIN模式:指定处理文本之前需要执行的操作
END模式:指定了处理文本之后需要执行的操作
BEGIN模式awk 'BEGIN{print "IP地址","端口号”}’ test.txt
awk会首先指定BEGIN模式指定的命令,打印两个字符串,并不会操作test.txt文件。
BEGIN模式awk 'BEGIN{print "IP地址","端口号"}{print $1,$2}' test.txt
BEGIN模式指定的命令,在开始处理文本内容之前执行,一次类推,在处理完文本美容之后,指定END模式指定的命令。
END模式awk '{print $1,$2}END{print "IP地址","端口号"}’ test.txt
BEGIN+END模式awk 'BEGIN{print "IP地址","端口号"}{print $1,$2}END{print “IP地址1",”端口号1"}' test.txt
可以同时处理文本的头、尾内容。
3.3简单介绍Option部分
上面我们学习了AWK中的'Pattern{Action}'部分,下面我们学习一下Option部分,即AWK命令的参数项。
上面我们提到了AWK可以指定分隔符,默认的额分隔符是“空格”,其实分隔符也分为两类:输入分隔符、输出分隔符。
格式化文本数据输入分隔符:FS,用于指定输入的格式文本时,按照何种分隔符进行列的划分。
输出分隔符:OFS,用于输出格式文本的时候,用何种分隔符进行列的划分。
awk -F# '{print $1,$3}’ 1test.txt
用-F参数项指定已#为列的分隔符。
AWK按照指定分隔符进行列的划分还有另外一种方式可以用于指定输入的分隔符:
AWK按照指定分隔符进行列的划分awk -v FS='#' '{print $1,$3}’ 1test.txt
同理我们可以使用-v OFS="||"参数选项英语用于指定文本的分隔符。
awk -v FS="#" -v OFS="||" '{print $1,$3}' 1test.txt
AWK按照指定分隔符分割列并按照指定输出分隔符输出再次说明一下AWK命令的形式:
awk [options] 'Pattern{Action}' file
-F用于指定输入的分隔符你、-V用于设置变量,都属于[Options]的一种。
至此,我们已经简单的介绍了[options] 'Pattern{Action}' 三部分了,已经可以简单的使用AWK了。
3.4 简单介绍一下AWK中的变量
接下来了解一下AWK的变量:
AWK中的变量,可以分为“内置变量”、“自定义变量”两种,其中输入分隔符、输出分隔符都属于内置的变量。
内置变量:就是在AWK中预先定义好的、内置为AWK内部的变量。
自定义变量:就是用户定义的变量。
AWK的常用内置变量例如:NR,用来表示每一行的行号,可以在输出文本的时候显示行号:
NR:显示每一行的行号NF变量则记录了每一行一共有多少列:
NF:统计显示每一行有多少列此时,打印的每一行首尾的数字是对应的行一共有几列。
3.5 使用终端输出作为AWK的输入
除了使用AWK可以操作本机的文本数据之外,还可以直接处理其它命令行命令的输出流。
通过使用管道命令 | ,可以直接上上一个命令的输出作为AWK数据的输入。
AWK通过管道命令处理终端的输出流在上面的命令中,使用$3=="root"
表达式实现字符的匹配。
~ /匹配字符/
的比较操作,来模糊匹配第9列中存在sh字符串的行。
~ /匹配字符/中,匹配字符还要注意关键字的转义。
针对复杂字符串的处理,需要使用复合表达式:
例如:
# awk '($3 ~ /^\$[2-9][0-9]*\.[0-9][0-9]$/) && ($4=="Tech") { printf "%s\t%s\n",$0,"*"; } ' tecmint_deals.txt
含义说明:
- 表达式 1:
($3 ~ /^\$[2-9][0-9]*\.[0-9][0-9]$/)
;查找交易价格超过$20
的行,即只有当$3
也就是价格满足/^\$[2-9][0-9]*\.[0-9][0-9]$/
时值才为真值。- 表达式 2:
($4 == “Tech”)
;查找是否有种类为 “Tech
”的交易,即只有当$4
等于 “Tech
” 时值才为真值。 切记,只有当&&
操作符的两端状态,也就是两个表达式都是真值的情况下,这一行才会被打上(*)
标志。
3.6 写简单的AWK脚本
我的Mac系统里面AWK的安装目录在/usr/bin/awk下面,我们现在尝试像写shell脚本那样写一个简单的AWK脚本:
AWK脚本所以,AWK也是可以编程的奥!!
完成一个带有if-else判断的脚本:
带判断的AWK脚本使用 Shell 引用:
让我们用一个示例来演示如何在一条 awk 命令中使用 shell 引用来替代一个 shell 变量。在该示例中,我们希望在文件 /etc/passwd 中搜索一个用户名,过滤并输出用户的账户信息。
AWK脚本3awk.sh的内容:
#!/bin/bash
### 读取用户名
read -p "请输入用户名:" username
### 在 /etc/passwd 中搜索用户名,然后在屏幕上输出详细信息
cat /etc/passwd | awk "/$username/ "' { print $0 }’
使用Shell变量
使用 awk 进行变量赋值
也可以通过定义AWK自变量的方式实现上面的功能:
使用AWK自变量注意:
分析一下 awk 脚本' $0 ~ name {print $0}'
中的$0 ~ name
。value ~ pattern
便是比较运算符之一,它是指:如果value(匹配的内容区域)
匹配了pattern(需要被匹配的内容)
则返回true
。进而该部分通过匹配的行信息会在{Action}命令中继续进行处理。
Next命令
next
命令在编写高效的命令脚本时候是非常重要的,它可以提高脚本速度
Next命令awk '$3 > 10 { print $0,"大于10" ; next; } $3<10 { print $0,"小于10"} ' test.txt
当输入行用命令'$3 > 10 { print $0,"大于10" ; next; } 打印以后,next
命令将跳过第二个$3<10 { print $0,"小于10"}表达式的判断,继续判断下一个输入行,而不是浪费时间继续判断一下是不是当前输入行还小于10。
4. 总结
以上只是简单的介绍了AWK的使用,这只是AWK强大功能的冰山一角,更详细的教程推荐!AWK在工业界的处理格式化文本数据的场景中具有广泛的使用,尤其是NLP相关的算法工程师,针对线上的大数据我们可能直接借助公司的Spark数据平台来处理,但针对线下的一些较大的格式化文本数据,AWK脚本语言或许是一个不错的选择!
推荐参考:
Linux 三剑客:
- sed命令参考:http://man.linuxde.net/sed
- grep命令参考:http://man.linuxde.net/grep
- AWK命令参考:http://man.linuxde.net/awk
网友评论