awk 使用

语法:

awk [options] 'pattern {action}' file

示例文件并将其保存为 colours.txt
name       color  amount
apple      red    4
banana     yellow 6
strawberry red    3
grape      purple 10
apple      green  8
plum       purple 2
kiwi       brown  4
potato     brown  9
pineapple  yellow 5
打印列

输出第二列的所有内容;显示全部列,请使用 $0;
awk '{print $2;}' colours.txt

有条件地选择列

查看第二列中与 yellow 匹配的项并打印第一列的内容:
awk '$2=="yellow"{print $1}' colours.txt

使用正则表达式,第二列中开头结尾为 p 的:
awk '$2 ~ /p.+p/ {print $0}' colours.txt

数字能被 awk 自然解释。例如,要打印第三列包含大于 5 的整数的行:
awk '$3>5 {print $1, $2}' colours.txt

字段分隔符

默认情况下,awk 使用空格作为字段分隔符(多个空格将被视为一个分隔符;其他分隔符,在程序中不是这么处理)。使用 --field-separator(或简称为 -F)选项来定义分隔符。
awk -F"," '$2=="yellow" {print $1}' file1.csv

保存输出

使用输出重定向,可以将结果写入文件:
awk -F, '$3>5 {print $1, $2} colours.csv > output.txt

可用选项

-F 定义字段分隔符
-e 突出显示(但这不是必须的)

示范:
awk -F " ", -e '{print $2;}' colours.txt

字段和记录

awk 将输入数据视为一系列记录,通常是按行分割的。换句话说,awk 将文本中的每一行视作一个记录。每一记录包含多个字段。一个字段由字段分隔符分隔开来,字段是记录的一部分。
默认情况下,awk 将各种空白符,如空格、制表符、换行符等视为分隔符。值得注意的是,在 awk 中,多个空格将被视为一个分隔符。

程序只会显示包含单词 “strawberry” 的记录:
`awk ‘/strawberry/ { print $0 }’ colours.txt

NF 变量

NF 变量,能存储 awk 在当前记录中找到的字段数量:

$ awk '{ print $0 " (" NF ")" }' colours.txt
name       color  amount (3)
apple      red    4 (3)
banana     yellow 6 (3)
[...]

awk 的 print 函数会接受一系列参数(可以是变量或者字符串),并将它们拼接起来。这就是为什么在这个例子里,每行结尾处,awk 会以一个被括号括起来的整数表示字段数量。

NR 变量

另外,除了统计每个记录中的字段数,awk 也统计输入记录数。记录数被存储在变量 NR 中,它的使用方法和其他变量没有任何区别。例如,为了在每一行开头显示行号:

$ awk '{ print NR ": " $0 }' colours.txt
1: name       color  amount
2: apple      red    4
3: banana     yellow 6
4: raspberry  red    3
5: grape      purple 10
[...]

注意,写这个命令时可以不在 print 后的多个参数间添加空格,尽管这样会降低可读性。

printf() 函数

为了让输出结果时格式更灵活,你可以使用 awk 的 printf() 函数。它与 C、Lua、Bash 和其他语言中的 printf 相类似。它也接受以逗号分隔的格式参数。参数列表需要写在括号里。

printf 格式, 项目1, 项目2, ...
格式这一参数(也叫格式符)定义了其他参数如何显示。这一功能是用格式修饰符实现的。%s 输出字符,%d 输出十进制数字。下面的 printf 语句,会在括号内显示字段数量:

awk '{printf "%s (%d)\n",$0,NF}' colours.txt
name       color  amount (3)
raspberry  red    4 (3)
banana     yellow 6 (3)

在这个例子里,%s (%d) 确定了每一行的输出格式,$0,NF 定义了插入 %s 和 %d 位置的数据。注意,和 print 函数不同,在没有明确指令时,输出不会转到下一行。出现转义字符 \n 时才会换行。

Awk 脚本编程

面对更复杂的程序,将命令放在文件(脚本)中会更容易。-f FILE 选项(不要和 -F 弄混了,那个选项用于字段分隔符),可用于指明包含可执行程序的文件。
举个例子,下面是一个简单的 awk 脚本。创建一个名为 example1.awk 的文件,包含以下内容:

/^a/ {print "A: " $0}
/^b/ {print "B: " $0}

如果一个文件包含 awk 程序,那么在给文件命名时,最好写上 .awk 的扩展名。这样命名不是强制的,但这么做,会给文件管理器、编辑器(和你)一个关于文件内容的很有用的提示。

一个包含 awk 命令的文件,在最开头一行加上释伴 #!,就能变成可执行脚本。创建一个名为 example2.awk 的文件,包含以下内容:

#!/usr/bin/awk -f
#
# 除了第一行,在其他行前显示行号
#
NR > 1 {
    printf "%d: %s\n",NR,$0
}

可以说,脚本中只有一行,大多数情况下没什么用。但在某些情况下,执行一个脚本,比记住,然后打一条命令要容易的多。一个脚本文件,也提供了一个记录命令具体作用的好机会。以 # 号开头的行是注释,awk 会忽略它们。
给文件可执行权限:

 chmod u+x example2.awk

执行:

./example2.awk colours.txt
2: apple      red    4
2: banana     yellow 6
4: raspberry red    3
5: grape      purple 10
[...]

将 awk 命令放在脚本文件中,有一个好处就是,修改和格式化输出会更容易。在终端中,如果能用一行执行多条 awk 命令,那么输入多行,才能达到同样效果,就显得有些多余了。

测试:

#!/usr/bin/awk -f
#
#  显示所有记录 除了出现以下情况
#  如果第一个记录 包含 “raspberry”
#  将 “red” 替换成 “pi”
$1 == "strawberry" {
        gsub(/red/,"pi")
}
{ print }
参考:
  1. https://linux.cn/article-11543-1.html
  2. https://mp.weixin.qq.com/s/du1y9pa2XBV8R8SMbuOXTA
  3. 手册:https://www.gnu.org/software/gawk/manual/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值