如何在Linux中使用awk命令如何在Linux中使用awk命令如何在Linux中使用awk命令如何在Linux中使用awk命令
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在Linux中使用awk命令

文本处理是 Unix 的核心。从管道到 /proc 子系统,“一切都是文件”的理念渗透到操作系统以及为其构建的所有工具中。因此,对于有抱负的 Linux 系统管理员甚至任何高级用户来说,熟悉文本处理是最重要的技能之一,而 awk 是通用编程语言之外最强大的文本处理工具之一。

最简单的 awk 任务是从 stdin 中选择字段;如果您对 awk 的了解从未超过此,您仍然可以使用一个非常有用的工具。

默认情况下,awk 用空格分隔输入行。如果您想从输入中选择第一个字段,您只需告诉 awk 打印出 $1:


$ echo 'one two three four' | awk '{print $1}'

one

(是的,大括号语法有点奇怪,但我保证这和本课中的一样奇怪。)

您能猜出如何选择第二个、第三个或第四个字段吗?没错,分别是 $2、$3 和 $4。


$ echo 'one two three four' | awk '{print $3}'

three

通常,在文本修改时,您需要创建特定格式的数据,并且它不仅仅涵盖单个单词。好消息是,awk 可以轻松打印多个字段,甚至包括静态字符串:


$ echo 'one two three four' | awk '{print $3,$1}'

three one

$ echo 'one two three four' | awk '{print "foo:",$3,"| bar:",$1}'

foo: three | bar: one

好的,但是如果您的输入没有用空格分隔怎么办?只需将 -F 标志与分隔符传递给 awk 即可:


$ echo 'one mississippi,two mississippi,three mississippi,four mississippi' | awk -F , '{print $4}'

four mississippi

有时,您可能会发现自己正在处理具有不同数量字段的数据,并且您只知道您需要最后字段。 awk 使用字段数量预填充$NF 变量,因此您可以使用它来获取最后一个元素:


$ echo 'one two three four' | awk '{print $NF}'

four

如果您需要倒数第二个字段,您还可以对 $NF 进行简单的数学运算:


$ echo 'one two three four' | awk '{print $(NF-1)}'

three

甚至是中场:


$ echo 'one two three four' | awk '{print $((NF/2)+1)}'

three

$ echo 'one two three four five' | awk '{print $((NF/2)+1)}'

three

虽然这一切都非常有用,但您也可以通过强制 sed、cut 和 grep 到表单中来获得这些结果(尽管需要做更多的工作)。

因此,我将向您介绍 awk 的最后一项介绍性功能,即跨行维护状态。


$ echo -e 'one 1ntwo 2' | awk '{print $2}'

1
2

$ echo -e 'one 1ntwo 2' | awk '{sum+=$2} END {print sum}'

3

(END 表示我们应该仅在处理完每一行之后执行以下块。)

我使用它的情况是总结网络服务器请求日志中的字节。假设我们有一个如下所示的访问日志:


$ cat requests.log

Jul 23 18:57:12 httpd[31950]: "GET /foo/bar HTTP/1.1" 200 344
Jul 23 18:57:13 httpd[31950]: "GET / HTTP/1.1" 200 9300
Jul 23 19:01:27 httpd[31950]: "GET / HTTP/1.1" 200 9300
Jul 23 19:01:55 httpd[31950]: "GET /foo/baz HTTP/1.1" 200 6401
Jul 23 19:02:31 httpd[31950]: "GET /foo/baz?page=2 HTTP/1.1" 200 6312

我们知道最后一个字段是响应的字节数。我们已经学习了如何使用 print 和 $NF 提取它们:


$ < requests.log awk '{print $NF}'

344
9300
9300
6401
6312

因此,我们可以将其汇总到一个变量中,以收集我们的网络服务器在日志时间跨度内为客户端提供服务的字节总数:


$ < requests.log awk '{totalBytes+=$NF} END {print totalBytes}'

31657

如果您正在寻找有关 awk 的更多信息,我建议您获取原始 awk 编程书籍的副本。您可能还会喜欢 Eric Pement 的 awk 俏皮话合集。

©2015-2025 艾丽卡 support@alaica.com