文章目录
前言
awk 可以说是 linux 运维人员必备的一门语言命令了,而且开发和测试人员也应该掌握它,awk 善于对文本进行处理,理论上可以替代 grep 命令
我为什么要把 awk 单独拿出来做一篇博文呢?因为 awk 功能确实太强大了,grep 和 sed 相对而言要好掌握不少,awk 其本身就算是一门编程语言,awk 脚本的写法可以说是非常灵活的,理论上可以替代 grep,所以我觉得很有必要将 awk 专门拎出来做一篇学习总结 awk 脚本的博文!
一些心得
有的人会认为初学 awk 的时候命令太多,太难记忆了,而且语法规则有些难以理解,其实不然,我们可以用这样的视角去看 awk 命令,我们可以把 awk 这个命令执行脚本的过程看成一个大的 for 循环,且是按行来循环,action 中我们去写对当前行中每一列进行的操作,这样看 awk 就会发现简单了许多,另外 awk 多了一个模式匹配的东西,这个模式匹配我们就直接看成遍历到当前行,里头写的一个条件语句即可,再另外 BEGIN 语句和 END 语句分别看成在 for 循环开头和 for 循环结束后的操作即可。很简单对吧!
历史溯源
awk 为什么叫做 awk 呢?因为其命名源于三位大佬的名字首字母:Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符,这几位是 awk 工具的创始人
awk 基本格式
# 直接依进行 awk 命令操作
awk [option] 'pattern{action}' var=value file(s)
# 可以依据文件中的 awk 命令脚本进行操作,-f 指定 awk 脚本的文件
awk [option] -f scriptfile var=value file(s)
awk 执行顺序
我们先看一个例子
# 写法一
awk '{FS=":"} {pirnt $1}'
# 写法二
awk 'BEGIN{FS=":"} {pirnt $1}'
# 写法三
awk -F ':' '{print $1}'
写法一我们认为它是按照:
做分割输出第一列,实际上并不是,写法二才是正确的。那为什么会导致这种情况的产生呢?因为在没有指定 BEGIN 变量的时候,awk 命令会先去读取第一行数据,它不会管你的 FS 设置为多少,awk 命令的底层操作顺序就是先直接去读取第一行数据,使用默认空格分隔符,然后发现命令中有 FS 分割,但已经读取了第一行改不了分割的规则了,所以第一行直接打印,然后从第二行开始分割都是正常的了。
所以我们明白一个道理就是像 FS 这类改变 awk 行数据排列规则的命令应该在前面带上 BEGIN,让其在读取第一行之前就应该被处理到!
用写法三也是正确的
awk 的大致流程就是逐行处理,把行作为赋值给 $0
,然后将 $0
按照默认空格符做切分,切分为 $1, $2, $3...
,然后执行编程动作,最后输出到屏幕
awk 如何分割语句
awk 基本分隔样式
# awk 选项 '模式语句{动作语句}'
awk [option] 'pattern{action}'
awk 自成一门编程语言,语句的分隔是有特点的。涉及到''
,{}
,,
这些符号,我们总结出特点有以下三点:
- 1.被
{}
包裹的是 awk 的 action 动作,也就是说下面 awk 的各种语法放在{}
才能被 awk 语法编译执行,{}
中被识别为 awk 的语法 - 2.
{}
中,awk 的脚本语句之间需要用;
隔开,这一点与其他编程语言类似 - 3.
{}
外,单引号内的空间是模式语句,模式可以直接做真假值的判定,不用加 if 语句,比如NR==1
,awk 会逐行进行的判定,当 awk 遍历到该行的时候,若此条件判定为真,就会输出该行相应的数据,否则不输出
基本形式如下:
# 组合语句
{
statements;...}
# 基本写法
awk