Linux运行结果是nan,[转载]Linux gawk

本文介绍了gawk命令的使用,包括其作为Unix中awk的GNU版本,如何处理文本文件中的数据,以及如何通过字段分隔符、变量和正则表达式进行数据操作。示例展示了gawk如何读取、打印数据字段,以及如何根据不同的字段分隔符处理文件。此外,还解释了gawk的内置变量如FNR、NR、NF等的作用,并给出了多个实际应用场景,如查看TCP连接状态、分析Apache日志等。
摘要由CSDN通过智能技术生成

gawk 命令

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

lrwxrwxrwx 1 root root 4 Mar

27 2010

/bin/awk -> gawk

gawk命令格式

Usage: gawk [POSIX or GNU style

options] -f progfile [--] file ...

Usage: gawk [POSIX or GNU style

options] [--] '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 “Hello

World!”,接下去{print $0}是我们输入的数据,输入之后回车会立刻显示相应的内容,也就是我们输入的内容,直到按ctrl-D,然后该gawk命令接结束了,但是结束之后还要之END后的结尾命令{print “byebye”}。这样整个过程就结束了。

gawk数据字段和记录变量

变量

描述

FIELDWIDTHS

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

FS

输入字段分隔符号

RS

输入记录分隔符号

OFS

输出字段分隔符号

ORS

输出记录分隔符号

默认情况下,gawk将OFS变量设置为空格:

[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

data11data12data13

data21data22data23

data31data32data33

更多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变量时,不需要再变量名称前加美元符号。

FNR、NF和NR变量在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变量包含数据文件中最后一个数据字段的数值。通过在前面加美元符号,可以将其作为数据字段变量使用。

FNR和NR变量相类似,只是略有不同。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,"records

processed"}' 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变量在处理第二个数据文件时仍然继续增加。也就是说,如果只使用一个

文件作为输入,则FNR和NR值将是相同的。如果使用多个数据文件作为输入,则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的查询

[root@wh tmp]# cat

ga.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]# cat

ga.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进行分类统计,然后对统计结果的求和。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值