Linux gawk 命令

来源:互联网 发布:linux oracle启动命令 编辑:程序博客网 时间:2024/04/29 12:01


----------------------------------------------------------------------------------------------------------------------------


gawk 命令

gawk程序是Unix中原awk程序的GNU版本。现在我们平常使用的awk其实就是gawk,可以看一下awk命令存放位置,awk建立一个软连接指向gawk,所以在系统中你使用awk或是gawk都一样的。

lrwxrwxrwx 1 root root 4 Mar27  2010/bin/awk -> gawk

 

gawk命令格式

Usage: gawk [POSIX or GNU styleoptions] -f progfile [--] file ...

Usage: gawk [POSIX or GNU styleoptions] [--] 'program' file ...

gawk选项

选项

描述

-F fs

指定描绘一行中数据字段的文件分隔符

-f file

指定读取程序的文件名

-v var=value

定义gawk程序中使用的变量和默认值

-mf N

指定数据文件中要处理的字段的最大数目

-mr N

指定数据文件中的最大记录大小

-W keyword

指定gawk的兼容模式或警告级别

 

gawk的主要功能之一是其处理文本文件中数据的能力。它通过自动将变量分配给每行中的每个数据元素实现这一功能。默认情况下,gawk将下面的变量分配给在文本行中检测到的每个数据字段:

◆ $0表示整行文本

◆ $1表示文本行中的第一个数据字段

◆ $2表示文本行中的第二个数据字段

◆ $n表示文本行中的第n个数据字段

各数据字段依据文本行中的字段分隔符确定。gawk读取一行文本时,使用定义的字段分隔符描述各数据字段。gawk的默认字段分隔符是任意空白字符(如制表符或空格符)

我们来看一个简单的例子:

[root@wh tmp]# cat data1

One line of test text.

Two lines of test text.

Three lines of test text.

[root@wh tmp]# gawk '{print $1}' data1

One

Two

Three

该程序使用$1字段变量仅显示每个文本行中的第一个数据字段。

 

如果你想读取使用不同字段分隔符的文件,可以使用-F选项:

[root@wh tmp] [root@wh tmp]# gawk -F: '{print $1}'/etc/passwd

root

bin

daemon

adm

lp

sync

shutdown

halt

。。。

因为/etc/passwd文件中使用冒号分隔数据字段,所以使用–F

如果某个文件中使用了分号分隔数据字段,那么使用–F

以此类推

 

[root@wh tmp]# gawk 'BEGIN {print "Hello World!"} {print$0} END {print "byebye"}'

Hello World!

haha!!!  ç在此输入文本后回车,会在下一行显示内容。

haha!!!  çctrl-D

byebye

 

BEGIN关键字是在处理任何数据之前应用的命令,即执行该gawk命令行时首先会去执行BEGIN所指定的命令,这里是print “HelloWorld!”,接下去{print $0}是我们输入的数据,输入之后回车会立刻显示相应的内容,也就是我们输入的内容,直到按ctrl-D,然后该gawk命令接结束了,但是结束之后还要之END后的结尾命令{print “byebye”}。这样整个过程就结束了。

 

gawk数据字段和记录变量

变量

描述

FIELDWIDTHS

以空格分隔的数字列表,用空格定义每个数据字段的精确宽度

FS

输入字段分隔符号

RS

输入记录分隔符号

OFS

输出字段分隔符号

ORS

输出记录分隔符号

 

默认情况下,gawkOFS变量设置为空格:

[root@wh tmp]# cat data1

data11,data12,data13,data14,data15

data21,data22,data23,data24,data25

data31,data32,data33,data34,data35

[root@wh tmp]# gawk 'BEGIN{FS=","} {print $1,$2,$3}'data1

data11 data12 data13

data21 data22 data23

data31 data32 data33

 

通过设置OFS变量,可以使用任何字符串分隔符输出中的数据字段:

[root@wh tmp]# gawk 'BEGIN{FS=",";OFS="-"} {print$1,$2,$3}' data1

data11-data12-data13

data21-data22-data23

data31-data32-data33

[root@wh tmp]# gawk 'BEGIN{FS=",";OFS="--"} {print$1,$2,$3}' data1

data11--data12--data13

data21--data22--data23

data31--data32--data33

[root@wh tmp]# gawk'BEGIN{FS=",";OFS="<-->"} {print$1,$2,$3}' data1

data11<-->data12<-->data13

data21<-->data22<-->data23

data31<-->data32<-->data33

 

更多gawk内置变量

变量

描述

ARGC

出现的命令行参数的个数

ARGIND

当前正在处理的文件在ARGV中的索引

ARGV

命令行参数数组

CONVFMT

数字的转换格式(参见printf语句)。默认值为%.6g

ENVIRON

当前shell环境变量及其值的关联数组

ERRNO

当读取或关闭输入文件时发生错误时的系统错误

FILENAME

用于输入到gawk程序的数据文件的文件名

FNR

数据文件的当前记录号

IGNORECASE

如果设置为非0,则忽略gawk命令中使用的字符串的大小写

NF

数据文件中数据字段的个数

NR

已处理的输入记录的个数

OFMT

显示数字的输出格式。默认为%,6g

RLENGTH

匹配函数中匹配上的子字符串的长度

RSTART

匹配函数中匹配上的子字符串的开始索引

 

[root@wh tmp]# gawk 'BEGIN {print ARGC,ARGV[1]}'data1

2 data1

ARGC变量表示命令行上有两个参数。这包括gawk命令和data1参数(注意,程序脚本不是参数)。ARGV数组以索引0开始,它表示命令。第一个数组值是gawk命令后的第一个命令行参数。与shell变量不同的是在脚本中引用gawk变量时,不需要再变量名称前加美元符号。

 

FNRNFNR变量在gawk程序中用于跟踪数据字段和记录。有时,你可能不知道记录中具体有多少个数据字段。NF变量允许指出记录中的最后一个数据字段而不需要知道它的位置:

[root@wh tmp]# gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}'/etc/passwd

root:/bin/bash

bin:/sbin/nologin

daemon:/sbin/nologin

adm:/sbin/nologin

lp:/sbin/nologin

sync:/bin/sync

 

NF变量包含数据文件中最后一个数据字段的数值。通过在前面加美元符号,可以将其作为数据字段变量使用。

 

FNRNR变量相类似,只是略有不同。FNR变量包含当前数据文件中处理的记录数。NR变量包含已经处理的记录的总数。让我们看几个例子来了解它们的不同之处:

[root@wh tmp]# gawk 'BEGIN{FS=",";} {print $1,"FNR="FNR}'data1 data1

data11 FNR=1

data21 FNR=2

data31 FNR=3

data11 FNR=1

data21 FNR=2

data31 FNR=3

 

本例中,gawk程序命令行定义了两个输入文件(它两次都指定了同一输入文件)。脚本打印第一个数据字段的值和FNR变量的当前值。请注意,FNR变量在gawk程序处理第二个数据文件时被重新设置为1

现在,让我们添加NR变量,看看结果是什么:

[root@wh tmp]# gawk 'BEGIN{FS=",";} {print$1,"FNR="FNR,"NR="NR} END {print "There were",NR,"recordsprocessed"}' data1 data1

data11 FNR=1 NR=1

data21 FNR=2 NR=2

data31 FNR=3 NR=3

data11 FNR=1 NR=4

data21 FNR=2 NR=5

data31 FNR=3 NR=6

There were 6 records processed

 

FNR变量值在gawk处理第二个数据文件时被重置,但NR变量在处理第二个数据文件时仍然继续增加。也就是说,如果只使用一个文件作为输入,则FNRNR值将是相同的。如果使用多个数据文件作为输入,则FNR值在每次处理新的数据文件时重置,而NR值对所有数据文件进行累计计数。

 

使用正则表达式和匹配操作符

[root@wh tmp]# gawk 'BEGIN{FS=","} /11/{print $1}'data1

data11

[root@wh tmp]# gawk 'BEGIN{FS=","} /d/{print $1}'data1

data11

data21

data31

 

[root@wh tmp]# gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}'data1

data21,data22,data23,data24,data25

匹配操作符将第二个数据字段与正则表达式/^data2/进行比较,/^data2/表示以文本data2开头的字符串。

 

这是一种在gawk程序脚本中常用的,也是非常好用的方法,用于在数据文件中搜索特定的数据元素:

[root@wh tmp]# awk -F: '$1 ~ /root/ {print $1,$NF}'/etc/passwd

root /bin/bash

此示例在第一个数据字段中搜索文本root,当在记录中找到模式时,打印出记录的第一个和最后一个数据字段。

还可以通过!符号否定正则表达式的匹配:

$1 !~ /expression/

如果没有在记录中找到正则表达式,则程序脚本将应用到记录数据上:

[root@wh tmp]# gawk 'BEGIN{FS=","} $2 !~ /^data2/ {print$1}' data1

data11

data31

在本例中,gawk程序脚本打印记录的第二个数据字段不以data2开头的第一个数据字段。

 

除了正则表达式,还可以在匹配模式中使用数学。当数据字段中包含数值时,使用这一功能将非常得心应手。例如,想显示所有属于根用户组(组号为0)的系统用户:

[root@wh tmp]# gawk -F: '$4 == 0 {print $1}'/etc/passwd

root

sync

shutdown

halt

operator

 

可以使用常规的数学比较表达式:

◆ X == y

◆ X <= y

◆ X < y

◆ X > y

◆ X >= y

 

[root@wh tmp]# gawk -F, '$1 == "data" {print $1}'data1

[root@wh tmp]# gawk -F, '$1 == "data11" {print $1}'data1

data11

第一个测试不匹配任何记录,因为第一个数据字段值data不存在于任何记录。第二个测试匹配值为data11的一条记录。

 

接下去我们来一些实际使用的例子:

1)查看TCP连接状态

[root@Log-Storage-1 ~]# netstat-n |awk '$1 ~ /^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}' 

CLOSE_WAIT 5

ESTABLISHED 20

TIME_WAIT 61

 

2)对于apache日志中指定某个页面进行手动pv或是uv的查询

指定页面pv和uv:http://ga.sdo.com/wh/index/index.asp

 

[root@wh tmp]# catga.sdo.com_12.01.28.all |gawk '$7 ~ /\/wh\/index\/index\.asp/{++S[$7]} END {for(a in S) print a,S[a]}'

http://ga.sdo.com/wh/index/index.asp" 889

http://ga.sdo.com/wh/index/index.asp?" 2

第二行不是我们所需要的,所以我们要修改一下:

[root@wh tmp]# catga.sdo.com_12.01.28.all |gawk '$7 ~ /\/wh\/index\/index\.asp"/{++S[$7]} END {for(a in S) print a,S[a]}'

http://ga.sdo.com/wh/index/index.asp" 889

现在这个就是我们要的结果了,PV为889。

 

接下来我们查uv
[root@wh tmp]# cat ga.sdo.com_12.01.28.all |gawk '$7 ~/\/wh\/index\/index\.asp"/ {print $1}'|sort|uniq|wc -l

744

我们查到744,这个就是我们需要的UV了。


求和

[root@wh tmp]# cat ga.sdo.com_12.01.28.all |gawk'$7 ~ /htm/ {++S[$7]} END {for(a in S) print a,S[a]}'|gawk'{sum+=$2} END {print sum}'

4571

对包含htm的URL进行分类统计,然后对统计结果的求和。


0 0
原创粉丝点击