AWK简介

作者:赵燕燕

(一)AWK:

Linux下有很多基于文本的样式扫描和处理的工具,他们可以实现以文档的列或行为单位进行扫描处理,大大减轻了文本处理的工作量, 这样的命令包括sed, grep, sort以及find等等,awk是其中很优秀的一种。他的功能大大强于sed和grep.它不仅可以完成grep和sed所能完成的全部工作,还可以进行样式装入,流控制,数学运算,进程控制甚至变量和函数。awk不仅是一条命令,更是一种语言。

awk特别适合于重新格式化数据文件,它可以将输入数据分成若干个记录,每个记录可以分成以特定分割符分开的域,这样对于任何域都可以灵活的操作处理。 而且awk的语法又和shell与C有很多相似之处,便于学习。

下面的章节就简单得从变量, 命令格式,子函数等几个方面详细的介绍下awk.

(二)AWK的格式:

awk Option ' 'BIGIN' {动作语法} {动作语法} 'END' {动作语法}' file1 file2 …

1) Option:

Option指的是awk执行单引号部分之前进行的操作

-f: 运行awk文件

例如:awk -f filename

-F: 设置分隔符,

例如,设置分割符为 “|”

awk –F “|” ‘{print $1}’ filename

-v: 特殊操作,需要在执行单引号部分之前就执行的

例如,传递shell参数:awk -v var=$b '{print var, $var}' filename

2) BEGIN:

BEGIN是要在执行行处理之前就执行的,执行的动作用{}括起来。注意,此处awk并没有读入文档,也不知道要处理的文档的名字信息,关于文档的变量都被设置为null

3)END:

END是要在执行行处理之后执行的,所有变量的值都和处理完文档的值保持一致。执行的动作用{}括起来

4)行处理的动作:

行处理的动作夹在BEGIN{}和END{}之间, 可以包括模式匹配和行处理动作。 其中行处理动作要用{}括起来。模式匹配不包含在{}之中。

模式匹配:支持正则表达式的匹配

例如:awk ‘/^8*/’ file

awk ‘$2 >5 && $2<=15’ file

awk '$1 ~ /101/ {print $1}' file 匹配后执行动作

awk '$1>2 {print $1,$2}' file匹配后执行动作

行处理动作:包括字符串操作,数字操作等等。

而且数字操作可以实现数字和字符串的直接运算。

例如:awk -v s=123 '{n = 0 + s; print n}' filename

如果字符串不是以数字开头的,例如sads222, 就直接默认为这个变量为0。

如果字符串以数字开头,例如233asd,就直接截取数字的部分。

行处理动作的awk语法中循环,判断,输出等都与C语言很接近。这也是awk受到欢迎的一个原因。

例如: 找到以|分隔的test.txt文件中的第一列是以8开头的行数

awk -F | ''BEGIN'{d=0} /$1~^8/{d++} 'END'{print d}' filename

单引号的部分都可以完全放入到.awk的文件中

上面的命令行的例子,同样可以在文件中实现:

例如:可以编写file.awk:

BEGIN {d=0}

/$1~^8/{d++}

END {print d}

运行awk命令: awk -f file.awk test.txt

(三)AWK的变量:

1) 内置变量:

像shell语言一样,awk有一些内置变量。 这些变量使用户可以方便的控制想要获取的文件的属性信息:

$1, $2....处理行的第一列,第二列...

$0处理行的所有列

ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览的文件名
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符

例如:打印域的个数,已读的记录数,整行信息,第一个参数(0的话是全部)及用户(最后一个是取得系统的环境变量)

awk -F '#' '{print NF,NR,$0,ARGV[1],ENVIRON["USER"]}' test.txt

2) 变量

变量的表示基本与shell保持一致。任何定义的变量不需要初始化,awk会根据第一次定义的数值,确定类型。

3) 输入输出

输入:awk '/^8/{"echo '$1'"|getline d; print d}' test.txt

awk ‘BEGIN {“date”|getline d; print d}'

echo aaas | awk '{print $1}'

其他的awk引用外部变量的几种方法:

a. awk –v awkvar=$extvar…#使外部变量的作用域扩展到BEGIN{}

b. awk '<awk expression>' "awkvar=$extvar" filename #BEGIN段不可用

c. 在awk表达式中使用'$extvar'

d. 模式引用(在正则表达式中引用外部变量) '"$extvar"

e. 遍历外部数组(用于BEGIN段处理) awk 'BEGIN{for(i=1;i<ARGC;i++)print ARGV[i]}' ${extarr[@]}

f. 引用环境变量 ENVIRON["environment variable"]

例如:awk中引用shell的变量

export变量,然后用ENVIRON[“var”]
#!/bin/bash
var="test"
export var
awk 'BEGIN{print ENVIRON["var"]}'
使用-v选项。
#!/bin/bash
var="test"
awk -v nvar="$var" 'BEGIN{print nvar}'

使用" "

awk '{print awkvar}' "awkvar=$var" filename

使用' '

awk '{print '$var'}' filename

例如:Shell中使用awk传递出来的变量

eval $(awk 'BEGIN{print "var1=along;var2=test"}')
echo "var1:"$var1
echo "var2:"$var2

输出:print, echo,重定向...

(四)子函数

子函数的定义与C, C++等其他的语言的定义是一致的 :

例如一个awk可以写成:

function gcd(x, y)

{

x = int(x)

y = int(y)

print x,y

r = x % y

return (r == 0)? y : gcd(y, r)

}

BEGIN {print "BEGIN"}

{g = gcd($1, $2); print "gcd("$1" ,"$2") =",g}

END {print "END"}

避免变量污染,可以在子函数中使用局部变量。例子中function factorial(n, i)的i就是在定义局部变量,n是从主函数中传递过来的值。

function factorial(n, i)

{

s=1;

for (i=1; i<=n; i++)

{

s*=i;

}

return s;

}

{

for (i=1;i<=10;i++)

{

value=factorial(i);

printf("fac(%d)=%d\n",i,value);

}

}

同样可以这样定义: function factorial(n, _ARGVEND_, i), 其中的_ARGVEND_的表示正常的调用所需要的形参到此结束。后面的假形参只是局部变量的定义。

(五)调试

Awk可以简单的作为单条的命令并结合输入输出,进行调试。

另外,如果想要查看运行中调试全局变量, 可以使用-dump-variables 参数。 例如调用上面的文件:echo "" | awk -f fac.awk --dump-variables=/tmp/var.dump

查看var.dump文件,就会把所有的属性信息,变量信息打印出来

ARGC: number (1)

ARGIND: number (0)

ARGV: array, 1 elements

BINMODE: number (0)

CONVFMT: string ("%.6g")

ERRNO: number (0)

FIELDWIDTHS: string ("")

FILENAME: string ("-")

FNR: number (1)

FS: string (" ")

IGNORECASE: number (0)

LINT: number (0)

NF: number (0)

NR: number (1)

OFMT: string ("%.6g")

OFS: string (" ")

ORS: string ("\n")

RLENGTH: number (0)

RS: string ("\n")

RSTART: number (0)

RT: string ("\n")

SUBSEP: string ("\034")

TEXTDOMAIN: string ("messages")

i: number (11)

s: number (3628800)

value: number (3628800)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值