我的新浪微博:http://weibo.com/u/1602714773 CSDN博客:http://blog.csdn.net/hunterno4

Linux Shell笔记之gawk

上一篇 / 下一篇  2013-12-22 17:09:36 / 个人分类:Linux

gawk:Unix中原始awk程序的GNU版本,强大之处在于可以写脚本来读取文本行的数据,然后处理并显示数据。
命令格式:gawk options program file

一、gawk基础
1.命令行读取程序脚本

# gawk '{print "hello world"}'           //gawk假定脚本是单个文本字符串,须将脚本放到单引号中
hello
hello world
hi
hello world

2.数据字段变量
文本行中发现的数据元素使用$0、$1等来分配变量
$0代表整个文本行
$1代表文本行中的第1个数据字段,$2等依次类推
默认分隔符为空白字符
# gawk '{print $1}' data1
this
# gawk -F: '{print $1}' passwd                                   //使用-F来指定字段分隔符
root
bin
daemon
adm

3.使用多个命令
# echo "this is a test" | gawk '{$4="gawk";print $0}'            //使用;号隔开
this is a gawk

4.从文件中读取程序
# cat gawktest 
{
text="'s home directory is "
print $1 text $6                                                 //gawk程序中使用变量无需加美元符
}
# gawk -F: -f gawktest passwd 
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm

5.BEGIN与END
# cat beginend 
BEGIN {                                            //BEGIN处理数据前运行的脚本
print "userid   shell"
print "------   -----"
FS=":"                                             //FS脚本中定义分隔符
}

{
print $1 "      " $7                               //引号内为制表符,这样输出的结果才能对齐
}

END {                                              //END处理数据后运行的脚本
print "end of list"
}
# gawk -f beginend passwd 
userid  shell
------  -----
root    /bin/bash
bin     /sbin/nologin
daemon  /sbin/nologin
adm     /sbin/nologi
...
end of list

二、gawk进阶
1.使用变量
1)内建变量

FIELDWIDTHS              由空格分隔开的定义了每个数据字段确切宽度的一列数字
FS                       输入字段分隔符
RS                       输入数据行分隔符
OFS                      输出字段分隔符
ORS                      输出数据行分隔符

# cat data1
data1.data2.data3
data4.data5.data6
# gawk 'BEGIN{FS=".";OFS="-"} {print $1,$2,$3}' data1
data1-data2-data3
data4-data5-data6

# cat datanumber 
1234.567.827                           //使用了FIELDWIDTHS变量,gawk会忽略FS变量,一旦设置不能改变
# gawk 'BEGIN{FIELDWIDTHS="1 2 3 4"} {print $1,$2,$3,$4}' datanumber 
1 23 4.5 67.8

2.数据变量
ARGC                      当前命令行参数个数
ARGV                      包含命令行参数的数组
ENVIRON                   当前shell环境变量及其值组成的关联数组
FNR                       当前数据文件中的数据行数
NF                        数据文件中的字段总数
NR                        已处理的输入数据行数目

# gawk 'BEGIN{print ARGC,ARGV[0]}' data1            //引用gawk变量,不用加$符号
2 gawk

]# gawk '
> BEGIN{
> print ENVIRON["HOME"]                             //提取HOME变量
> print ENVIRON["PATH"]
> }'
/root
/usr/local/program/jdk1.6.0_33/bin

# gawk 'BEGIN{FS=":";OFS="-"} {print $1,$NF}' passwd         //NF指定数据行中的最后一个数据字段
root-/bin/bash
bin-/sbin/nologin
daemon-/sbin/nologin

3.自定义变量
# cat script1 
#!/bin/bash

BEGIN{print "the n value is",n;FS="."}
{print $n}

# gawk -f script1 n=3 data1
the n value is 
data3
data6

# gawk -v n=3 -f script1 data1                    //BEGIN代码之前设定的变量需要用-v参数指定
the n value is 3
data3
data6

4.处理数组
1)定义数组                         //与哈希表类似
格式: var[index]= element  
    
# gawk 'BEGIN{
> capital["shanghai"]="shanghai"
> print capital["shanghai"]
> }'
shanghai   

2)遍历数组
# gawk 'BEGIN{
> var["g"]=1
> var["a"]=2
> var["w"]=3
> var["k"]=4
> for(test in var)
> {
>    print "index:",test," - value:",var[test]                //中间有逗号
> }
> }'
index: w  - value: 3                                //输出值只能保证一一对应,不能按顺序
index: k  - value: 4
index: a  - value: 2
index: g  - value: 1

3)删除数组
# cat script2
#!/bin/bash
BEGIN{
var["g"]=1
var["a"]=2
var["w"]=3
var["k"]=4
for(test in var)
{
   print "index:",test," - value:",var[test]
}
delete var["a"]                             //删除指定数组中的数据元素
print "---"
for(test in var)
{
   print "index:",test," - value:",var[test]
}

}

# gawk -f script2
index: w  - value: 3
index: k  - value: 4
index: a  - value: 2
index: g  - value: 1
---
index: w  - value: 3
index: k  - value: 4
index: g  - value: 1

5.使用模式
1)正则表达式
# gawk 'BEGIN{FS="."} /1/{print $1}' data1            //匹配data1文件中含有1的
data1

2)匹配操作符
波浪线~,匹配操作符可以将正则表达式限定在数据行中的特一数据字段
# gawk -F: '$1 ~ /root/{print $1,$NF}' passwd               //查找第一个数据字段中匹配root的数据
root /bin/bash

# gawk -F: '$1 !~ /root/{print $1,$NF}' passwd               //波浪线前加!号,排除匹配到的数据
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown

3)数学表达式
可以使用普通数学表达式,x == y; x<=y;x>y 等等
# gawk -F: '$4 == 0{print $1}' passwd            //查找第四个数据字段为0,即属于root用户组的用户
root
sync
shutdown
halt
operator

6.结构化命令
1)if语句
# cat script3
#!/bin/bash
{
if ($1 <5)
{
   x = $1 + 20
   print x
} else
{
   x = $1 + 30
   print x
}
}

# gawk -f script3 dataif 
21
22
23
24
35
36
37
38

2)while语句
# cat datawhile 
12 13 14
45 56 78
22 33 44

# cat script4
#!/bin/bash
{
total=0
i=1
while (i<4)
{
   total += $i
   i++
}
avg = total / 3
print "avg:",avg
}

# gawk -f script4 datawhile 
avg: 13
avg: 59.6667
avg: 33

3)for语句
# cat script5
#!/bin/bash
#!/bin/bash
{
total=0
i=1
for (i=1;i<4;i++)
{
   total += $i
}
avg = total / 3
print "avg:",avg
}

7.格式化输出
printf格式化输出

c          将一个数作为ASCII字符显示
d          显示一个整数值
e          科学计数法显示
f          显示浮点数
o          显示一个八进制值
s          显示一个文本字符串
x          显示一个十六进制值
X          显示一个十六进制值,但用大写字母A-F

# cat script5
#!/bin/bash
#!/bin/bash
{
total=0
i=1
for (i=1;i<4;i++)
{
   total += $i
}
avg = total / 3
printf "avg: %5.1f\n",avg              //近似到小数点1位
}

8.内建函数
gawk提供了一些内置函数
1)数学函数
exp(x)      x的指数函数
int(x)      x的整数部分
rand()      0至1之间的随机浮点数

x=int(10 * rand())

2) 字符串函数
asort(s [,d])           将数组s按数据元素值排序
index(s,t)              返回字符串t在字符串s中的索引值
length([s])             返回字符串s的长度

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

# gawk 'BEGIN{
> date = systime()
> day = strftime("%A,%B %d,%Y",date)
> print day
> }'
Sunday,December 22,2013

TAG: gawk Linux shell Shell 变量 函数

 

评分:0

我来说两句

Open Toolbar