您当前的位置:首页 > 电脑百科 > 软件技术 > 操作系统 > linux

Linux技巧:awk 命令简单入门介绍

时间:2020-03-27 13:35:56  来源:  作者:

Linux技巧:awk 命令简单入门介绍

 

linux 命令中,awk 命令常用于处理文本内容。下面基于实例介绍 awk 命令的常见用法。

GNU gawk

awk 既是一个命令,也是一种程序语言,它可以有不同的实现版本。

在 Linux 系统中,awk 的实现版本是 GNU gawk。

在 shell 中执行 awk 命令,实际执行的是 gawk 命令。如下所示:

$ ls -l /usr/bin/awk
lrwxrwxrwx 1 root root 21  2月  1  2019 /usr/bin/awk -> /etc/alternatives/awk
$ ls -l /etc/alternatives/awk
lrwxrwxrwx 1 root root 13  3月  8  2019 /etc/alternatives/awk -> /usr/bin/gawk
$ ls -l /usr/bin/gawk
-rwxr-xr-x 1 root root 441512  7月  3  2013 /usr/bin/gawk

可以看到,/usr/bin/awk 文件最终链接到 /usr/bin/gawk 文件,/usr/bin/gawk 文件没有再链接到其他文件。

在下面的描述中,如无特别说明,所说的 awk 是指 GNU gawk。

awk 命令格式

查看 man awk 的说明,也是链接到 man gawk 的内容,这个说明比较难懂,不够清晰,可以再参考 GNU gawk 在线帮助手册 https://www.gnu.org/software/gawk/manual/gawk.html 的说明。

下面引用的内容就出自这个在线帮助手册,其中对 awk 的基本介绍如下:

The basic function of awk is to search files for lines (or other units of text) that contain certain patterns.

When a line matches one of the patterns, awk performs specified actions on that line.

awk continues to process input lines in this way until it reaches the end of the input files.

awk 命令的基本用法说明如下:

There are several ways to run an awk program.

If the program is short, it is easiest to include it in the command that runs awk, like this:awk 'program' input-file1 input-file2 …

where program consists of a series of patterns and actions, an awk program looks like this:

pattern { action }

 

When the program is long, it is usually more convenient to put it in a file and run it with a command like this:

awk -f program-file input-file1 input-file2 …

 

There are single quotes around program so the shell won’t interpret any awk characters as special shell characters.

The quotes also cause the shell to treat all of program as a single argument for awk, and allow program to be more than one line long.

 

You can also run awk without any input files. If you type the following command line:

awk 'program'

awk Applies the program to the standard input, which usually means whatever you type on the keyboard.

即,awk 命令在所给文件中查找包含特定模式的行,并对找到的行进行特定处理。这些特定处理由 program 参数指定。

上面提到,所给的 program 参数要用单引号括起来,避免 shell 对一些特殊字符进行扩展。

如果没有提供文件名,awk 命令默认会读取标准输入。

如果没有提供特定模式,默认处理所有行。

注意:跟在 awk 命令的 program 参数后面的参数会被认为是文件名,即使用引号把参数值括起来也还是当成文件名,不会当成字符串。

这个命令不能处理命令行参数提供的字符串值,具体举例说明如下:

$ cat testawk
This is a test string.
This is another TEST string.
$ awk '{print $3}' testawk
a
another
$ awk '{print $3}' "testawk"
a
another
$ awk '{print $3}' "This is a test string."
awk: fatal: cannot open file `This is a test string.' for reading (No such file or directory)

可以看到,awk '{print $3}' testawk 命令打印出 testawk 文件的第三列内容。

awk '{print $3}' "testawk" 命令也是打印出 testawk 文件的第三列内容。即使用双引号把 testawk 括起来,也不代表是打印 "testawk" 字符串的第三列。

而 awk '{print $3}' "This is a test string." 命令会执行报错,提示找不到名为 This is a test string. 的文件,它不会处理 "This is a test string." 这个字符串自身的内容,而是把该字符串当成文件名,要处理对应文件的内容。

如果确实需要用 awk 命令来处理字符串,可以用管道操作符 | 来连接标准输入。

例如用 echo 命令打印字符串的值,然后通过管道操作符把这个值传递到 awk 命令的标准输入。

具体举例如下:

$ echo "This is a test string." | awk '{print $4}'
test
$ value="This is a new test string."
$ echo "$value" | awk '{print $4}'
new

可以看到,echo "This is a test string." | awk '{print $4}' 命令通过 echo 先输出字符串的值,再通过管道操作符 | 把这个输出连接到 awk 命令的标准输入,就能对这个字符串进行处理,不会执行报错。

echo "$value" | awk '{print $4}' 命令打印出 value 变量值的第四列内容,可以用这个方式来对变量值进行处理。

注意:这里使用管道操作符 | 来连接标准输入,让 awk 命令能够处理传入到标准输入的字符串,但是使用重定向标准输入操作符 < 并不能让 awk 命令处理字符串。

重定向是基于文件的操作,所给的字符串会被当成文件名,举例如下:

$ awk '{print $4}' < "This is a test string."
-bash: This is a test string.: No such file or directory

可以看到,在重定向标准输入操作符 < 右边的 "This is a test string." 字符串被当成文件名,bash 提示找不到文件。

这里不是 awk 命令报错,而是 bash 在处理重定向的时候报错。

awk program

使用 awk 命令的关键在于,program 参数要怎么写。

查看 GNU gawk 在线帮助手册的说明,列举部分内容如下:

  • Programs in awk consist of pattern–action pairs.
  • An action without a pattern always runs.
  • An awk program generally looks like this: [pattern] { action }
  • Patterns in awk control the execution of rules -- a rule is executed when its pattern matches the current input record.
  • The purpose of the action is to tell awk what to do once a match for the pattern is found.
  • An action consists of one or more awk statements, enclosed in braces (‘{…}’).

即,awk 命令的 program 参数由 pattern 和 action 组成。Pattern 用于指定匹配模式,并对匹配的行执行后面的 action 操作,不匹配的行不做处理。Action 用于指定要对匹配到的行进行什么样的操作,这些操作语句要包含在大括号 {} 里面。如果没有提供 pattern 参数,默认处理所有行。

部分 pattern 参数的写法说明如下:

  • /regular expression/
    A regular expression. It matches when the text of the input record fits the regular expression.
  • expression
    A single expression. It matches when its value is nonzero (if a number) or non-null (if a string).

具体举例说明如下:

$ awk '/a.*/ {print $0}' testawk
This is a test string.
This is another TEST string.
$ awk '/test/ {print $0}' testawk
This is a test string.
$ awk 'test {print $0}' testawk
$ awk '"NONE" {print $0}' testawk
This is a test string.
This is another TEST string.
$ awk '$3 == "another" {print $0}' testawk
This is another TEST string.

可以看到,awk '/a.*/ {print $0}' testawk 命令使用 a.* 正则表达式来匹配包含字符 ‘a’ 的行,然后打印出整行内容。

awk '/test/ {print $0}' testawk 命令则是打印包含 "test" 字符串的行。

awk 'test {print $0}' testawk 命令什么都没有打印,这种写法并不表示打印包含 "test" 字符串的行。

awk '"NONE" {print $0}' testawk 命令打印出 testawk 文件的所有行,虽然这个文件并没有包含 "NONE" 字符串。基于上面说明,所给的 pattern 参数是一个用双引号括起来的非空字符串,表示总是匹配,不管这个字符串的内容是什么。

awk '$3 == "another" {print $0}' testawk 命令匹配第三列内容为 "another" 字符串的行,并打印出整行内容。

即,如果要指定匹配某个字符串,pattern 参数写为 “/regular expression/” 的形式会比较简单,要写为 “expression” 形式,需要了解 awk 的表达式写法。

获取所给行的内容

awk 在读取每行内容时,会基于分割字符把行内容拆分成多个单词,可以用 $number 来获取第 number 列的单词,number 值从 1 开始。例如,$1 对应第一列的单词,$2 对应第二列的单词,$3 对应第三列的单词,依此类推。可以用 $NF 来获取拆分后的最后一列内容。

特别的,$0 获取到整行的内容,包括行首、或者行末的任意空白字符。

以 "This is a test string." 这一行进行举例,有如下的对应关系:

Linux技巧:awk 命令简单入门介绍

awk行字段获取方法

使用 -F 选项指定分割字符

前面提到,awk 默认使用空格来拆分行内容为多个单词。如果想要基于其他字符来进行拆分,可以使用 -F 选项来指定分割字符。

GNU gawk 在线帮助手册对 -F 选项说明如下:

-F fs

--field-separator fs

Set the FS variable to fs.

例如对 "clang/utils/analyzer/" 这样的目录路径来说,如果想要基于 / 进行拆分,以便获取各个目录名,就可以使用 -F 选项来指定分割字符为 /

具体举例如下:

$ echo "clang/utils/analyzer/" | awk -F '/' '{print $1, $2}'
clang utils
$ echo "clang/utils/analyzer/" | awk -F '/' '{print "Last word is: " $NF}'
Last word is: 

可以看到,使用 -F '/' 指定分割字符后,所给内容会以 / 来进行拆分,拆分后的单词不包含 ‘/’ 这个字符。

由于所给内容的最后一个字符是 ‘/’,最后一列拆分后的内容为空,所以 $NF 的内容为空。

当需要基于特定字符分割行内容时,使用 awk 命令特别实用,-F 选项可以指定分割字符,然后用 $number 就能获取到第 number 列的内容,方便处理。

print 语句

前面的例子都用了 print 语句来打印内容。

GNU gawk 在线帮助手册对 print 语句的说明如下:

Use the print statement to produce output with simple, standardized formatting.

You specify only the strings or numbers to print, in a list separated by commas.

They are output, separated by single spaces, followed by a newline.

The statement looks like this:

print item1, item2, …

 

The entire list of items may be optionally enclosed in parentheses.

The simple statement ‘print’ with no items is equivalent to ‘print $0’: it prints the entire current record.

即,print 语句打印所给字符串、或者数字的内容,不同内容之间要用逗号 ‘,' 隔开,但是打印出来的效果是用空格隔开。

经过测试,如果用其他字符隔开会不生效,打印的内容会连在一起。具体举例说明如下:

$ awk '/test/ {print $3, $5}' testawk
a string.
$ awk '/test/ {print $3 $5}' testawk
astring.
$ awk '/test/ {print $3_$5}' testawk
astring.

可以看到,在 print 后面写为 $3, $5 时,打印的两个字符串用空格隔开,而写为 $3 $5、或者 $3_$5,打印的两个字符串直接连在一起,没有打印所给的空格、或者下划线 ‘_’。即,只能用逗号来隔开。

如果在 print 后面没有提供参数,默认相当于 print $0,会打印整行内容。如果没有提供任何 action 参数,连大括号 {} 都不提供,默认相当于 { print $0 }。如果只提供大括号 {},大括号里面没有内容,则是空操作,什么都不做。

具体举例如下:

$ awk '/test/ {print}' testawk
This is a test string.
$ awk '/test/' testawk
This is a test string.
$ awk '/test/ {}' testawk

可以看到,awk '/test/ {print}' testawk 命令在 print 后面提供参数,打印出整行内容。

awk '/test/' testawk 命令没有提供 action 参数,也是打印出整行内容。

awk '/test/ {}' testawk 命令提供了 action 参数,只是没有指定要做的操作,什么都没有打印。



Tags:awk 命令   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在 Linux 命令中,awk 命令常用于处理文本内容。下面基于实例介绍 awk 命令的常见用法。GNU gawkawk 既是一个命令,也是一种程序语言,它可以有不同的实现版本。在 Linux 系统...【详细内容】
2020-03-27  Tags: awk 命令  点击:(76)  评论:(0)  加入收藏
▌简易百科推荐
作用显示文件或目录所占用的磁盘空间使用命令格式du [option] 文件/目录命令功能显示文件或目录所占用的磁盘空间一些写法的区别du -sh xxx 显示总目录的大小,但是不会列出...【详细内容】
2021-12-23  mitsuhide1992    Tags:du命令   点击:(12)  评论:(0)  加入收藏
什么是linux内核linux就像是一个哲学的最佳实践。如果非要对它评价,我真的不知道该怎么赞叹,我只能自豪地说着:“linux的美丽简直让人沉醉。”我只能说是我处在linux学习的修炼...【详细内容】
2021-12-23  linux上的码农    Tags:linux内核   点击:(15)  评论:(0)  加入收藏
本文将比较 Linux 中 service 和 systemctl 命令,先分别简单介绍这两个命令的基础用法,然后进行比较。从 CentOS 7.x 开始,CentOS 开始使用 systemd 服务来代替 service服务(dae...【详细内容】
2021-12-23  软件架构    Tags:systemctl   点击:(14)  评论:(0)  加入收藏
mv是move的缩写,可以用来移动文件或者重命名文件名,经常用来备份文件或者目录。命令格式mv [选项] 源文件或者目录 目标文件或者目录命令功能mv命令中第二个参数类型的不同(...【详细内容】
2021-12-17  入门小站    Tags:mv命令   点击:(23)  评论:(0)  加入收藏
大数据技术AI Flink/Spark/Hadoop/数仓,数据分析、面试,源码解读等干货学习资料 98篇原创内容 -->公众号 Linux sed 命令是利用脚本来处理文本文件。sed 可依照脚本的指令来处...【详细内容】
2021-12-17  仙风道骨的宝石骑士    Tags:sed命令   点击:(22)  评论:(0)  加入收藏
Node是个啥?  写个东西还是尽量面面俱到吧,所以有关基本概念的东西我也从网上选择性地拿了下来,有些地方针对自己的理解有所改动,对这些概念性的东西有过了解的可选择跳过这段...【详细内容】
2021-12-15  linux上的码农    Tags:node   点击:(25)  评论:(0)  加入收藏
难道只有我一个人觉得Ubuntu的unity桌面非常好用吗?最近把台式机上面的Ubuntu 16.04格式化了,装了黑苹果用了一周,不得不说,MacOS确实很精美,软件生态比Linux丰富很多,比Windows简...【详细内容】
2021-12-14  地球末日村    Tags:ubuntu   点击:(40)  评论:(0)  加入收藏
简介Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。输出信息含义执行net...【详细内容】
2021-12-13  窥镜天    Tags:Linux netstat   点击:(28)  评论:(0)  加入收藏
对于较多数量的文件描述符的监听无论是select还是poll系统调用都显得捉襟见肘,poll每次都需要将所有的文件描述符复制到内核,内核本身不会对这些文件描述符加以保存,这样的设计...【详细内容】
2021-12-13  深度Linux    Tags:Linux   点击:(19)  评论:(0)  加入收藏
今天,我们来了解下 Linux 系统的革命性通用执行引擎-eBPF,之所以聊着玩意,因为它确实牛逼,作为一项底层技术,在现在的云原生生态领域中起着举足轻重的作用。截至目前,业界使用范...【详细内容】
2021-12-10  架构驿站    Tags:eBPF   点击:(29)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条