美文网首页
gawk 相关总结

gawk 相关总结

作者: 杨仕杰 | 来源:发表于2018-08-14 13:19 被阅读0次

一. gawk 基础

gawk 程序脚本用一对花括号来定义,必须将命令放到两个花括号中。由于 gawk 命令行假定脚本是单个文本字符串,所以还必须将脚本放到单引号中。

gawk 允许将多条命令组合成一个正常的程序。要在命令行上的程序脚本中使用多条命令,只要在命令之间加分号即可。

gawk 具有如下功能:

  • 定义变量来保存数据

  • 使用算术和字符串操作符来处理数据

  • 使用结构化编程概念来为数据处理增加处理逻辑

  • 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告

(一). 命令格式

gawk options program file
选项 描述
-F fs 指定行中划分数据字段的字段分隔符
-f file 从指定的文件中读取程序
-v var=value 定义gawk程序中的一个变量及其默认值
-mf N 指定要处理的数据文件中的最大字段数
-mr N 指定数据文件中的最大数据行数
-W keyword 指定 gawk 的兼容模式或警告等级

(二). BEGIN 关键字

gawk 允许指定程序脚本何时运行。gawk 默认会从输入中读取一行文本,然后针对该行的数据执行程序脚本。有时可能需要在处理数据前运行脚本,比如为报告创建标题。BEGIN 关键字会强制 gawk 在读取数据前执行 BEGIN 关键字后指定的程序脚本。

$ cat data.txt 
Line 1
Line 2
Line 3

$ gawk 'BEGIN {print "The data3 File Contents:"} {print $0}' data.txt 
The data3 File Contents:
Line 1
Line 2
Line 3

(三). END 关键字

与 BEGIN 关键字类似,END 关键字允许指定一个程序脚本,gawk 会在读完数据后执行它。

$ gawk '{print $0} END {print "End of file"}' data.txt 
Line 1
Line 2
Line 3
End of file

二. 使用变量

gawk 支持两种不同类型的变量:内建变量、自定义变量。内建变量存放用来处理数据文件中的数据字段和记录的信息。

(一). 内建变量

1. 字段变量

字段变量允许使用美元符号 $ 和字段在该记录中的位置来引用记录对应的字段。因此使用 $0 代表整行文本,使用 $1 引用记录中的第一个数据字段,使用 $2 引用第二个字段,依次类推。

2. 分隔符变量

字段变量是由字段分隔符来划定的。

变量 描述
FIELDWIDTHS 由空格分隔的一列数字,定义了每个数据字段确切宽度
FS 输入字段分隔符 (默认为空白字符)
RS 输入记录分隔符 (默认为换行符)
OFS 输出字段分隔符 (默认为空格)
ORS 输出记录分隔符 (默认为换行符)

FIELDWIDTHS 变量允许我们不依靠字段分隔符来读取记录。在一些应用中,数据并没有使用字段分隔符,而是被放置在了记录中的特定列。这种情况下,必须设定 FIELDWIDTHS 变量来匹配数据在记录中的位置。

一旦设置了 FIELDWIDTH 变量, gawk 就会忽略 FS 变量,并根据提供的字段宽度来计算字段。一旦设定了 FIELDWIDTHS 变量的值,就不能再改变了。

$ cat data.txt 
1005.3247596.37
115-2.349194.00
05810.1298100.1

$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"} {print $1,$2,$3,$4}' data.txt 
100 5.324 75 96.37
115 -2.34 91 94.00
058 10.12 98 100.1

3. 数据变量

变量 描述
ARGC 当前命令行参数个数
ARGIND 当前文件在 ARGV 中的位置
ARGV 包含命令行参数的数组
CONVFMT 数字的转换格式,默认值为%.6 g
ENVIRON 当前 shell 环境变量及其值组成的关联数组
ERRNO 当读取或关闭输入文件发生错误时的系统错误号
FILENAME 用作 gawk 输入数据的数据文件的文件名
FNR 当前数据文件中的数据行数
IGNORECASE 设成非零值时,忽略 gawk 命令中出现的字符串的字符大小写
NF 数据文件中的字段总数
NR 已处理的输入记录数
OFMT 数字的输出格式,默认值为 %.6 g
RLENGTH 由 match 函数所匹配的子字符串的长度
RSTART 由 match 函数所匹配的子字符串的起始位置

ARGC 和 ARGV 变量允许从 shell 中获得命令行参数的总数以及它们的值。但这可能有点麻烦,因为 gawk 并不会将程序脚本当成命令行参数的一部分。

$ gawk 'BEGIN {print ARGC,ARGV[0],ARGV[1]}' data.txt 
2 gawk data.txt

ENVIRON 变量使用关联数组来提取 shell 环境变量。数组索引中的文本是环境变量名,而数组的值则是对应环境变量的值。

$ gawk 'BEGIN {print ENVIRON["HOME"]; print ENVIRON["PATH"]}'
/root
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

如果只使用一个数据文件作为输入,FNR 和 NR 的值是相同的;如果使用多个数据文件作为输入,FNR 的值会在处理每个数据文件时被重置,而 NR 的值则会继续计数直到处理完所有的数据文件。

$ cat data.txt 
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ gawk 'BEGIN{FS=","}{print $1,"NFR="FNR,"NR="NR}' data.txt data.txt 
data11 NFR=1 NR=1
data21 NFR=2 NR=2
data31 NFR=3 NR=3
data11 NFR=1 NR=4
data21 NFR=2 NR=5
data31 NFR=3 NR=6

(二). 自定义变量

gawk 自定义变量名可以是任意数目的字母、数字和下划线,但不能以数字开头。变量名区分大小写。

1. 在脚本中给变量赋值

$ gawk 'BEGIN {test="this is a test"; print test}'
this is a test

$ gawk 'BEGIN {x=4; x=x*2+3; print x}'
11

2. 在命令行给变量赋值

$ cat data.txt 
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ cat script 
BEGIN {FS=","}
{print $n}

$ gawk -f script n=2 data.txt 
data12
data22
data32

使用命令行参数来定义变量的值会有一个问题,这个值在代码的 BEGIN 部分不可用。可以用 -v 命令行参数来解决这个问题。它允许在 BEGIN 代码之前设定变量。在命令行上,-v 命令行参数必须放在脚本代码之前。

$ cat data.txt 
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ cat script 
BEGIN {FS=",";print "The value is", n}
{print $n}

$ gawk -f script n=2 data.txt 
The value is 
data12
data22
data32

$ gawk -v n=2 -f script data.txt 
The value is 2
data12
data22
data32

三. 处理数组

在 gawk 中使用关联数组提供数组的功能。关联数组不需要使用连续的数字来标识数组中的数据元素,而是用各种字符串来引用值。每个索引字符串都必须能够唯一地标识出赋给它的数据元素。

(一). 定义数组

数组变量赋值的格式为:var[index] = element。其中 var 是变量名,index 是关联数组的索引值,element 是数据元素值。

$ gawk 'BEGIN {
num[1]=2
num[2]=3
str["name"]="ziqing"
total=num[1]+num[2]
print str["name"],total
}'
ziqing 5

(二). 遍历数组

如果要在 gawk 中遍历一个关联数组,可以用特殊的 for 语句。for 语句在每次循环时将关联数组 array 的下一个索引值赋给变量 var,然后执行一遍 statements。这个变量中存储的是索引值而不是数组元素值。索引值不会按任何特定顺序返回。

for (var in array)
{
    statements
}
$ gawk 'BEGIN {
arr["a"]=1
arr["b"]=2
arr["c"]=3
arr["d"]=4
for (var in arr)
{
    print "key:",var," value:",arr[var]
}
}'
key: a  value: 1
key: b  value: 2
key: c  value: 3
key: d  value: 4

(三). 删除数组变量

从关联数组中删除数组索引要用一个特殊的命令:delete array[index]。删除命令会从数组中删除关联索引值和相关的数据元素值。

$ gawk 'BEGIN {
arr["a"]=1
arr["b"]=2
arr["c"]=3
arr["d"]=4
for (var in arr)
{
    print "key:",var," value:",arr[var]
}
print "============="
delete arr["b"]
for (var in arr)
{
    print "key:",var," value:",arr[var]
}
}'
key: a  value: 1
key: b  value: 2
key: c  value: 3
key: d  value: 4
=============
key: a  value: 1
key: c  value: 3
key: d  value: 4

四. 使用模式

(一). 正则表达式

$ cat data.txt 
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ gawk 'BEGIN{FS=","} /11/{print $1,$2}' data.txt 
data11 data12

(二). 匹配操作符

匹配操作符 (~) 允许将正则表达式限定在记录中的特定数据字段。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。也可以用 ! 符号来排除正则表达式的匹配。

$ cat data.txt 
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ gawk 'BEGIN{FS=","} $1 ~ /^data2/{print $1,$2}' data.txt 
data21 data22

$ gawk 'BEGIN{FS=","} $1 !~ /^data2/{print $1,$2}' data.txt 
data11 data12
data31 data32

(三). 数学表达式

可以在匹配模式中使用数学表达式。这在匹配数据字段中的数字值时非常方便。也可以对文本数据使用表达式,数据必须跟模式严格匹配。

$ gawk -F: '$4 == 0{print $1}' /etc/passwd
root
sync
shutdown
halt
operator

五. 结构化命令

(一). if 语句

if (condition) statement1
if (condition) statement1; else statement2
$ cat data.txt 
10
5
13
50
34

$ gawk '{if($1 > 20) print $1}' data.txt 
50
34
$ cat data.txt 
10
5
13
50
34

$ gawk '{if($1 > 20) print $1; else print $1 *2}' data.txt 
20
10
26
50
34

(二). while 语句

gawk 支持在 while 循环中使用 break 语句和 continue 语句,允许从循环中跳出。

while (condition)
{
    statements
}
$ cat data.txt 
130 120 135
160 113 140
145 170 215

$ gawk '{i=1;total=0;while(i<4){total=total+$i;i++;};print "total: "total}' data.txt 
total: 385
total: 413
total: 530

(三). do-while 语句

do
{
    statements
} while (condition)
$ cat data.txt 
130 120 135
160 113 140
145 170 215

$ gawk '{
i=1;total=0
do{total=total+$i;i++;}while(total<150)
print "total:"total
}' data.txt 
total:250
total:160
total:315

(四). for 语句

for( variable assignment; condition; iteration process)
$ gawk 'BEGIN{total=0;for(i=1;i<=10;i++)(total=total+i);print "total: "total}'
total: 55

六. 格式化打印

gawk 中的 printf 命令允许指定具体如何显示数据的指令。

printf "format string", var1, var2 . . .

format string 是格式化输出的关键。它会用文本元素和格式化指定符来具体指定如何呈现格式化输出。格式化指定符会指明显示什么类型的变量以及如何显示。gawk 会将每个格式化指定符作为占位符,供命令中的变量使用。第一个格式化指定符对应列出的第一个变量,第二个对应第二个变量,依此类推。

格式化指定符格式:%[modifier]control-letter。其中 control-letter 是一个单字符代码,用于指明显示什么类型的数据,而 modifier 则定义了可选的格式化特性。

控制字母 描述
c 将一个数作为 ASCII 字符显示
d 显示一个整数值
i 显示一个整数值(跟 d 一样)
e 用科学计数法显示一个数
f 显示一个浮点值
g 用科学计数法或浮点数显示(选择较短的格式)
o 显示一个八进制值
s 显示一个文本字符串
x 显示一个十六进制值
X 显示一个十六进制值,但用大写字母 A~F

除了控制字母外,还有 3 种修饰符可以用来进一步控制输出:

  • width,指定输出字段最小宽度的数字值。如果输出短于这个值,printf 会将文本右对齐,并用空格进行填充。如果输出比指定的宽度还要长,则按照实际的长度输出

  • prec,指定浮点数中小数点后面位数,或者文本字符串中显示的最大字符数

  • -,指明在向格式化空间中放入数据时采用左对齐而不是右对齐

七. 内建函数

一. 数学函数

函数 描述
atan2(x, y) x/y 的反正切, x 和y 以弧度为单位
cos(x) x 的余弦, x 以弧度为单位
exp(x) x 的指数函数
int(x) x 的整数部分,取靠近零一侧的值
log(x) x 的自然对数
rand( ) 比 0 大比 1 小的随机浮点值
sin(x) x 的正弦, x 以弧度为单位
sqrt(x) x 的平方根
srand(x) 为计算随机数指定一个种子值

int() 会生成一个值的整数部分,但并不会四舍五入取近似值。它会生成该值和 0 之间最接近该值的整数。

函数 描述
and(v1, v2) 执行值 v1 和 v2 的按位与运算
compl(val) 执行 val 的补运算
lshift(val, count) 将值 val 左移 count 位
or(v1, v2) 执行值 v1 和 v2 的按位或运算
rshift(val, count) 将值val右移 count 位
xor(v1, v2) 执行值 v1 和 v2 的按位异或运算

二. 字符串函数

asort(s [,d])

将数组 s 按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。如果指定了d,则排序后的数组会存储在数组 d 中。

asorti(s [,d])

将数组 s 按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表明排序顺序。另外如果指定了 d,排序后的数组会存储在数组 d 中。

gensub(r, s, h [, t])

查找变量 $0 或目标字符串 t 来匹配正则表达式 r。如果 h 是一个以 g 或 G 开头的字符串,就用 s 替换掉匹配的文本。如果 h 是一个数字,它表示要替换掉第 h 处 r 匹配的地方。

gsub(r, s [,t])
查找变量 $0 或目标字符串 t来匹配正则表达式 r。如果找到了,就全部替换成字符串 s。

index(s, t)

返回字符串t在字符串 s 中的索引值,如果没找到的话返回 0

length([s])

返回字符串 s 的长度;如果没有指定的话,返回 $0 的长度。

match(s, r [,a])

返回字符串 s 中正则表达式 r 出现位置的索引。如果指定了数组 a,它会存储 s 中匹配正则表达式的那部分。

split(s, a [,r])

将 s 用 FS 字符或正则表达式 r 分开放到数组 a 中。返回字段的总数。

sprintf(format,variables)

用提供的 format 和 variables 返回一个类似于 printf 输出的字符串。

sub(r, s [,t])

在变量 $0 或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串 s 替换掉第一处匹配。

substr(s, i [,n])

返回 s 中从索引值 i 开始的 n 个字符组成的子字符串。如果未提供 n,则返回 s 剩下的部分。

tolower(s)

将 s 中的所有字符转换成小写。

toupper(s)

将 s 中的所有字符转换成大写。

三. 时间函数

函数 描述
mktime(datespec) 将一个按 YYYY MM DD HH MM SS [DST] 格式指定的日期转换成时间戳值
strftime(format[,timestamp]) 将当前时间的时间戳或 timestamp 转化格式化日期
systime( ) 返回当前时间的时间戳

相关文章

  • gawk 相关总结

    一. gawk 基础 gawk 程序脚本用一对花括号来定义,必须将命令放到两个花括号中。由于 gawk 命令行假定...

  • gawk

    gawk基本使用 gawk options program file gawk -F '{commond1;com...

  • gawk快速指南

    gawk是awk的GNU版本,采用编程语言的形式 gawk命令格式 gawk options program fi...

  • Linux中的部分awk命令 2019-11-18

    awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU...

  • 21. Linux awk 命令

    AWK 官方手册:http://www.gnu.org/software/gawk/manual/gawk.htm...

  • gawk Ⅰ

    awk vs gawk 除了VI这种交互式的文本编辑器(interactive text editor),Linu...

  • 硬盘容量邮件报警功能

    1. 安装gawk:sudo apt install gawk; 2. 安装mail:sudo apt-get i...

  • awk

    awk介绍 有多种版本:New awk(nawk),GNU awk(gawk) gawk:模式扫描和处理语言 基本...

  • linux shell编程中有的命令组合

    1、字符串转换大小写 gawk '{print toupper($0)}' //转换为大写 gawk '{prin...

  • awk

    tip awk经过改进生成的新的版本nawk,gawk. linux下是gawk 格式awk [options] ...

网友评论

      本文标题:gawk 相关总结

      本文链接:https://www.haomeiwen.com/subject/xuaomftx.html