资讯专栏INFORMATION COLUMN

awk 入坑指北

Vultr / 1067人阅读

摘要:传入参数在命令行下通过参数还可以给脚本传入参数,比如内置函数内置了很多字符串处理以及数学运算方面的函数,常用的如返回在中出现的索引。

awk(/ɔːk/) 是 *nix 下一种强大的文本处理工具,其名称取自三位作者 Alfred Aho,Peter Jay Weinberger,Brian Wilson Kernighan。awk 提供的功能包括不仅限于正则匹配、流控制、算术运算、甚至于函数等编程语言具备的一些特性。它发行于 1977 年,已经超过了 40 岁堪称古董级软件。为了更让人能直接明白它的用途,我把它称为是命令行下的 Excel,其中的一些概念和 Excel 有很多相似之处。

TR;DR

awk 是一种高效的文本处理工具。

awk 脚本的基本结构 BEGIN -> BODY -> END。

基本语法,awk 脚本语法和 C 语言很很多相似之处。

awk 脚本编程实践以及需要注意的地方。

基本用法

在 linux 环境下我们有一些文本处理需求时,awk 就能派上用场了,比如 nginx 的访问日志,文本信息去重等等。awk 可以直接在命令行中执行比如:

echo "" | awk "{print "hello world!"}"

也可以将一些逻辑比较复杂的代码写到一个 awk 脚本中,然后指定脚本文件执行:

awk -f a.awk test.txt
程序结构

awk 直接在命令行中输入和执行 awk 脚本效果是一样的,所以以下代码为了便于阅读都写入到一个脚本文件中。
一个完整的 awk 脚本分为三个部分:

BEGIN{ print("BEGIN");  }
{ print("BODY");  }
END{ print("END");  }

但是 awk 脚本要能正确执行只需要其中一个阶段就行,第一个阶段是 BEGIN,就是还未开始扫描输入文本时候的预处理时间,中间 BODY 是扫描文本执行阶段,awk 每扫描到输入文本一行数据就会执行 BODY 中的脚本代码,最后是 END,即文本扫描完成的阶段,在绝大部分使用场景中我们直接在 {} 中写代码就可以了,即省略掉了 BEGIN 和 END。

awk 理解输入

前面已经提到,我将 awk 视为 *nix 下的 Excel,下面提到的一些概念和 Excel 颇为相似。对于 awk 处理的文本一般情况下是一行一行的,比如 nginx 的日志文件,在 awk 的视角文本的一行被视为一条记录(Record)行以 n 来进行划分。在一行中通过空格又被分为多个域(Field),这就和 Excel 的行列差不多了。所以在 awk 程序中存在 2 个全局变量 NF,NR,这就很容易理解了。

需要值得注意的是域的索引不是从 0 开始的,而是从 1 开始,0 是当前行的引用,通过 $n 的语法来拿到不同域的值。

{
    # 当前记录有多少个域
    print("NF is:" NF);
    # 当前是第几条记录
    print("NR is:" NR);
    # 输出当前行的文本
    print($0);
    # 输出当前行的第一个域
    print($1);
}

以上代码中 print 是 awk 的一个内置函数,用于输出文本信息。在 awk 脚本中可以通过 # 号来写注释。

awk 语法

和很多脚本程序一样,awk 没有严格的数据类型,不同数据类型直接可以直接转换。在 awk 中声明的变量统统会成为全局变量,所以在一处修改了变量值,脚本其他地方也会受到影响。在流程控制上几乎和主流编程语言完全一样。if-else, while 都是支持的,在后续的列子中可以看到。

传入参数

在命令行下通过 -v 参数还可以给 awk 脚本传入参数,比如:

echo "" | awk -v name="jiavan" "{print("hello, "name);}"
内置函数

awk 内置了很多字符串处理以及数学运算方面的函数,常用的如:

index(str1, str2):返回 str2 在 str1 中出现的索引。

length(str):返回一个字符串的长度。

substr(str, n, m):截取字符串 str 的子串。

match(str, reg):正则匹配,返回第一次匹配索引。

.....
跟多使用可以 man 一下。

内置变量

awk 还内置了一些变量名:

$0            当前处理记录
$1-$n         当前记录的n个字段
FS            域分隔符
NF            当前记录的域数目
NR            已经处理的记录条数
RS            记录分隔符
OFS           输出字段分隔符
ORS           输出记录分隔符
ARGC          命令行参数个数
ARGV          命令行参数数组
FILENAME      当前输入文件名字
IGNRECASE     记录为真代表忽略大小写匹配
ARGIND        当前被处理文件的ARGV标志符
CONVFMT       数字转换格式 %.6g
ENVIRON       UNIX环境变量
ERRNO         UNIX系统错误消息
FIELDWIDTHS   输入字段宽度的空白分隔字符串
FNR           当前记录数
OFMT          数字的输出格式 %.6g
RSTART        被匹配函数匹配的字符串首
RLENGTH       匹配函数匹配的字符串长度
SUBSEP        34
PROCINFO      当前运行程序进程信息数组
awk 实践 文本去重

有以下具有重复文本的文件 name.txt。

// name.txt
jiavan
kellen
lzy
fakafang
jiavan
lzy
pig

// a.awk
{
    ++names[$1];
}
END {
    for (key in names) {
        print(key) > "./unique.txt";
    }
}

上方 a.awk 先遍历文件行存入一个数组,在 awk 中数组的 key 可以是任意数据类型,value 也可以是任意数据类型,名称每出现一次 +1,最后就能统计出每个名称出现的次数以及将所有不重复的 key 输出到一个文件中,这里的操作和 bash 类似。

搜寻字符串

对于输入的文本 words.txt,我们使用 awk 找出带有 av 关键字的单词。

// words.txt
this is a test file with some key words like average and avoid
--created by jiavan.

// b.awk
{
    while (match($0, /[a-zA-Z]+?av[a-zA-Z]+?/)) {
        print(substr($0, RSTART, RLENGTH));
        $0 = substr($0, RSTART + RLENGTH);
    }
}

// result
$ awk -f b.awk words.txt
average
avoid
av
jiavan

所以在 TX 游戏中我的 ID 是 Ji**an 这样显示的 :-)

本文仅提供给正在拉屎的人阅读,不做参考。

原文出处 https://github.com/Jiavan/jia... 觉得对你有帮助就给个star吧

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/10392.html

相关文章

  • 『并发包入坑指北』之向大佬汇报任务

    摘要:所以也很容易想到可以利用等待通知机制来实现,和上文的并发包入坑指北之阻塞队列的类似。 showImg(https://segmentfault.com/img/remote/1460000019021474?w=2785&h=2785); 前言 在面试过程中聊到并发相关的内容时,不少面试官都喜欢问这类问题: 当 N 个线程同时完成某项任务时,如何知道他们都已经执行完毕了。 这也是本次讨...

    Mike617 评论0 收藏0
  • 『并发包入坑指北』之阻塞队列

    摘要:自己实现在自己实现之前先搞清楚阻塞队列的几个特点基本队列特性先进先出。消费队列空时会阻塞直到写入线程写入了队列数据后唤醒消费线程。最终的队列大小为,可见线程也是安全的。 showImg(https://segmentfault.com/img/remote/1460000018811340); 前言 较长一段时间以来我都发现不少开发者对 jdk 中的 J.U.C(java.util.c...

    nicercode 评论0 收藏0
  • WSL 配置指北:打造 Windows 最强命令行

    摘要:截至目前,商店中可用的发行版有以及。尽管上的控制台已经改进了不少可以看看的官方博客,但其依然是最难用的终端模拟器之一,或许没有之一。因此,为了实现我们的目标,一个更强大的终端模拟器是必须的。上的老牌终端模拟器,功能极为强大,要啥有啥。 原文发表在我的 博客 上,欢迎订阅。;) 在两年前的八月,Microsoft 正式发布了 Windows 10 Anniversary Update 周...

    isaced 评论0 收藏0
  • 作为一个前端工程师也要掌握的几种文件路径知识

    摘要:前言之前在做配置时候多次用到路径相关内容,最近在写项目的时候,有一个文件需要上传到阿里云的功能,同时本地服务器也需要保留一个文件备份。如果返回的路径字符串长度为零,那么他会返回一个,代表当前的文件夹。 showImg(https://segmentfault.com/img/bVbwElJ?w=480&h=204); 前言 之前在做webpack配置时候多次用到路径相关内容,最近在写项...

    wslongchen 评论0 收藏0
  • Nginx 入门指北

    摘要:入门指北是一个高性能的和反向代理服务器。前端开发人员迈向全栈,服务器相关的技术是不可绕过的一个门槛。环境准备参考入门指北快速的搭建一个虚机,并默认安装好。键入编辑启动并检查状态在中上传一个文件。参考资料服务器上建立用户并分配权限 Nginx 入门指北 Nginx是一个高性能的HTTP和反向代理服务器。前端开发人员迈向全栈,服务器相关的技术是不可绕过的一个门槛。先以简单的nginx为切入...

    XiNGRZ 评论0 收藏0

发表评论

0条评论

Vultr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<