awk

awk 基本格式为:

awk [options] '[pattern]{action}' file/data

awk 处理数据的单元是行,它会遍历每一行,使用我们指定的条件来过滤,再执行 action 的操作。awk 使用数据库中的名词,一行叫做一个记录 (Record),一行中的一列叫做一个字段 (Field).

默认 awk 使用空格(以及连续的空格)作为字段分隔符。

输出 4~6 行的第一列和最后一列:

awk 'NR==4,NR==6{print $1, NF}'

参数选项

参数注释Example
-F修改输入分隔符-F ':' 使用冒号作为分隔符
-v修改变量-v FS=':' 等价于 -F ':'

常用内置变量

变量注释
$n第 n 个字段的内容,$0 表示一整行
NFNumber of Fields 当前记录的字段个数
NRNumber of Record 当前记录的序
FNR各个文件分别计数的行号
FS字段分隔符,默认空格
OFS输出时的字段分隔符
RS记录分隔符,默认换行。若超过 1 个字符则视为正则表达式
ORS输出时的记录分隔符

Pattern

内置模式

模式注释
BEGIN开始处理文本前执行,可用于打印表头
END处理完毕后执行

关系运算符

除了常见的几个:<, <=, >, >=, ==, != 外,还支持 /pattern/ 正则匹配,!/pattern/ 不匹配正则。

举例(忽略注释行):

> cat a.txt
abc
# comment
def

> awk '!/^#/{print $0}' a.txt
abc
def

区间匹配

使用逗号 , 分隔模式可以形成区间,例如 NR==1,NR==4 表示 1~4 行。除此之外,正则也可以用于区间,表示两行之间的所有记录。

Action

print

基本格式:

print value [,value]...
  • , 逗号用于隔开多个值,输出时 awk 会用 OFS 分隔它们。
  • 双引号里的值原样输出。

举例:

> cat a.txt
hello world
hello shell

> awk '{print "L" NR ":", $1 ", " $2 "!"}' a.txt
L1: hello, world!
L2: hello, shell!

printf

基本格式:

printf "format" value [,vale]...
  • 必须指定 format
  • 不会自动输出换行

格式参数

格式符注释
%c字符的 ASCII 码
%d, %i十进制整数
%e, %E科学计数法显示
%f浮点数
%g, %G科学计数法显示浮点数
%s字符串
%u无符号整数
%%显示一个百分号 '%'

修饰符

修饰符注释Example
-左对齐(默认右对齐)%-8s 8字符宽度,左对齐
+显示数值的符号%+d

举例:

> cat a.txt
3000 plus 100000 = 103000

> awk '{printf "%+d %s %d equals %e\n", $1, $2, $3, $5}' a.txt
+3000 plus 100000 equals 1.030000e+05

Example

传递 shell 变量

v=world
awk -v name=$v 'BEGIN{print "hello", name}'

删除 Docker Tag 为 none 的镜像

> docker images
REPOSITORY                        TAG       IMAGE ID       CREATED         SIZE
<none>                            <none>    c20f4abfa928   2 minutes ago   52.6MB
mysql                             5.7       2a0961b7de03   2 weeks ago     462MB
pushtechnology/docker-diffusion   6.8.2     8837db5dee43   6 weeks ago     361MB

> docker rmi `docker images | grep "<none>" | awk '{print $3}'`
Deleted: sha256:c20f4abfa928b56d56e111a47f89dca67ae2e95830dc5f030f5fb77a44ddc1a0
Last modification:June 12, 2022