awk 学习笔记:
------------
·模式:
开始-主输入循环-结束
·主输入循环:模式匹配-记录-字段
·变量表达的字段:
[root@localhost ~]# echo a b c|awk 'BEGIN {one=1;two=2} {print $(one + two)}'
c
·-f选项:
[root@localhost ~]# awk -f list.awk name.log
andy,3233
steve,77899
[root@localhost ~]# cat list.awk
BEGIN { FS = " " }
{print $1 "," $2}
[root@localhost ~]# cat name.log
andy 3233
steve 77899
·分割符:
两个连续的分隔符间的字段值为空串。
·多个分隔符:(使用正则表达式表示)
[root@localhost ~]# awk -F "[:,]" '{print $1,$3}' name.log
andy xx
steve yy
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
·awk中对于变量赋值,空格为字符串间的连接操作符。
·模式匹配+算术运算:
使用awk,对于空行进行计数的脚本:
[root@localhost ~]# awk -f null_row.awk name.log
2
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
end,0:z
[root@localhost ~]# cat null_row.awk
/^$/ {
++x
}
END {
print x
}
·算术运算:
求取平均值脚本:
[root@localhost ~]# awk -f avg_grade.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat avg_grade.awk
{
total = $2 + $3 + $4 + $5
avg = total / 4
print $1,avg
}
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
·系统变量
FS:输入字段分割符
OFS:输出字段分割符
RS:输入记录分隔符
ORS:输出记录分割符
NF:当前记录中字段的总数
NR:当前的记录数
FILENAME:当前输入处理的文件名
·横跨处理多行记录
[root@localhost ~]# awk -f multi_row.awk multi_row.log
andy steve 678-888
lucy lee 890-777
[root@localhost ~]# cat multi_row.log
andy steve
hangzhou
789 street
678-888
lucy lee
hangzhou
301 street
890-777
[root@localhost ~]# cat multi_row.awk
BEGIN {
FS = "\n"
RS = ""
}
{ print $1,$NF }
·关系操作符(主要用于模式匹配)
大于-等于-小于-匹配-不匹配:
等于的例子:
[root@localhost ~]# awk -F "[:,]" 'NF == 3 {print $1}' name.log
andy
steve
end
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
end,0:z
匹配的例子:
[root@localhost ~]# awk -F "[:,]" '$1 ~ /andy/ {print $1,$3}' name.log
andy xx
·逻辑(布尔)操作符
逻辑或-与-非
与的例子:
[root@localhost ~]# awk -F "[:,]" '$1 ~ /andy/ && $2 == 3233 {print $1,$2}' name.log
andy 3233
·格式化打印
print:打印字符串和字段,自动在句末加入回车;
printf:格式化输出,不会在句末自动加入回车,需要明确指定“\n”
[root@localhost ~]# awk '{printf "|%-10s|%3d\n",$1,$2}' grade.log
|andy | 86
|lily | 66
|lucy | 77
|steve | 82
|ann | 80
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
·向awk脚本传递参数(变量one、two)
[root@localhost ~]# awk -f var_input.awk one=1 two=2 grade.log
87 80
67 72
78 80
83 80
81 80
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat var_input.awk
{
$2 += one
$3 += two
print $2,$3
}
另外一种获取方法:(使用-v选项,POSIX awk支持)
[root@localhost ~]# awk -v one=1 -v two=2 -f var_input.awk grade.log
87 80
67 72
78 80
83 80
81 80
#####进阶部分#####
·条件语句(基本上合C语言语法类似,下同)
一个例子:计算平均分,并显示为等级:
[root@localhost ~]# awk -f gtoclass.awk grade.log
andy 79.75 C
lily 62.75 D
lucy 70.00 C
steve 75.75 C
ann 76.00 C
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat gtoclass.awk
{
total = $2 + $3 + $4 + $5
avg = total / ( NF -1 )
if (avg >= 90) class = "A"
else if (avg >= 80) class = "B"
else if (avg >= 70) class = "C"
else if (avg >= 60) class = "D"
else class = "E"
printf "%-10s%5.2f%5s\n",$1,avg,class
}
·循环语句
for while do-while
求平均值的另外一种方法:
[root@localhost ~]# awk -f for_avg.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat for_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg = total / (NF - 1)
print $1,avg
}
使用while时的类似方法:
[root@localhost ~]# awk -f while_avg.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat while_avg.awk
{
total = 0
i = 2
while ( i <= NF )
{
total += $i
i += 1
}
avg = total / (NF - 1)
print $1,avg
}
可以参考的一个综合的求阶乘的例子:
[root@localhost ~]# ./fact
enter number:5
the fact of 5 is 120
[root@localhost ~]# cat fact
awk '
BEGIN {
printf "enter number:"
}
$1 ~ /^[0-9]+$/ {
number = $1
if ( number == 0 )
fact = 1
else
fact = number
for ( x = number - 1;x > 1;x-- )
fact *= x
printf "the fact of %d is %g \n",number,fact
exit
}
{printf "invalid.enter number again:"}
' -
·影响程序流控制的语句
break:作用于循环语句,跳出循环
continue:作用于循环语句,跳出,进入下一个循环
next:作用于主输入循环,读取下一行输入行,返回到脚本顶部
exit:作用于主输入循环,退出主输入循环,将控制转移给END规则
·数组
选用NR作为数组下标的例子:
[root@localhost ~]# cat array_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg[NR] = total / (NF - 1)
}
END {
for ( x = 1;x <= NR;x++ )
class_avg_total += avg[x]
class_avg = class_avg_total / NR
for ( x = 1;x <=NR;x++ )
if ( avg[x] >= class_avg )
++above_avg
else
++below_avg
print "class avg:",class_avg
print "above avg:",above_avg
print "below avg:",below_avg
}
[root@localhost ~]# awk -f array_avg.awk grade.log
class avg: 72.85
above avg: 3
below avg: 2
·关联数组
数组的下标可以为字符串或数值
可以用于构造类似Python中的字典数据结构。
进行关联数组访问时,其输出数组条目顺序是随机的。
使用关联数组进行达到分数等级的个数的一个例子,综合以上各个内容:
[root@localhost ~]# awk -f fin_array_avg.awk grade.log
andy 79.75 C
lily 62.75 D
lucy 70 C
steve 75.75 C
ann 76 C
class avg: 72.85
above avg: 3
below avg: 2
C: 4
D: 1
[root@localhost ~]# cat fin_array_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg_arr[NR] = total / (NF - 1)
avg = avg_arr[NR]
if (avg >= 90) class = "A"
else if (avg >= 80) class = "B"
else if (avg >= 70) class = "C"
else if (avg >= 60) class = "D"
else class = "E"
++class_arr[class]
print $1,avg,class
}
END {
for ( x = 1;x <= NR;x++ )
class_avg_total += avg_arr[x]
class_avg = class_avg_total / NR
for ( x = 1;x <=NR;x++ )
if ( avg_arr[x] >= class_avg )
++above_avg
else
++below_avg
print "class avg:",class_avg
print "above avg:",above_avg
print "below avg:",below_avg
for ( class_x in class_arr )
print class_x ":",class_arr[class_x] | "sort"
}
·split进行数组创建
[root@localhost ~]# echo 2 |awk -f split_month.awk
2 II
[root@localhost ~]# cat split_month.awk
BEGIN {
split("I,II,III,IV,V",numb,",")
}
$1 > 0 && $1 <= 5 {
print $1,numb[$1]
exit
}
{
print "valid number."
exit
}
·多维数组
模拟引用多维数组
简单的例子:
BEGIN {
for (i = 1;i <= 2; ++i)
for ( j = 1; j <=2; ++j)
bitmap[i,j] = "O"
}
...
·系统变量数组
ARGV:awk+附带的参数(-f参数除外)组成的数组,下标从0开始;
ARGC:参数数组个数。
·函数
算术函数:
三角函数-对数函数-平方根函数-随机函数-取整函数
举例如下:
[root@localhost ~]# awk -f int_func.awk
33.3333
33
[root@localhost ~]# cat int_func.awk
BEGIN {
print 100/3
print int(100/3)
exit
}
字符串函数:
gsub(r,s,t):在t中将r匹配到所有字符串,匹配为s ;(t未输入时,默认为$0)
sub(r,s,t):在t中将r首次匹配到字符串,匹配为s ;(t未输入时,默认为$0)
index(s,t):返回t在s中的位置;否则返回0;
match(s,r):返回正则表达式r在s中的起始位置;否则返回0;
substr(s,p,n):返回s中p位置之后的那个字符;(n未输入时,返回p之后剩余的字符)
split(s,a,sep):将s根据sep分割后写入数组a中,返回数组元素个数;
length(s):返回s的长度;(s未输入时,默认为$0)
sprintf(“fmt”,expr)对于expr使用fmt格式说明
tolower(s):大写转化为小写
toupper(s):小写转化为大写
一些例子:
index和substr综合:
将第一个单词的首字符变为大写:
[root@localhost ~]# echo abc |awk -f index_substr.awk
Abc
[root@localhost ~]# cat index_substr.awk
BEGIN {
upper="ABCDEFGH"
lower="abcdfegh"
}
{
firstchar=substr($1,1,1)
if (charplace = index(lower,firstchar))
$1 = substr(upper,charplace,1)substr($1,2)
print $0
}
替换函数gsub和sub:
gsub的正则表达式替换,&为复制模式字符,\为转义符:(基本规则类似sed)
[root@localhost ~]# echo abc|awk '{gsub(/ab/,"\\start & end\\",$1);print $1}'
\start ab end\c
另外一个例子:
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat sub_gsub.awk
awk '
{
gsub(/"/,"")
if (sub(/an/,"An")) print
if (sub(/li/,"Li")) print
}' $*
[root@localhost ~]# ./sub_gsub.awk grade.log
Andy 86 78 99 56
Lily 66 70 59 56
Ann 80 78 90 56
match函数:
函数两个系统变量:RSTART,RLENGTH;
RSTART:匹配子串的开始位置;此为返回值,不匹配时,返回为0
RLENGTH:匹配字符串的字符数。
如使用match进行正则表达式的字符大小匹配,不同awk版本的实现不一致;
遇到不区分大小写的情况,如下:
[root@localhost ~]# cat test.awk
/[a-z]/{
print $0
}
[root@localhost ~]# echo ABC|awk -f test.awk
ABC
[root@localhost ~]# echo abc|awk -f test.awk
abc
[root@localhost ~]# echo 123|awk -f test.awk
[root@localhost ~]#
自定义函数:
在脚本的模式规则定义之前声明;
在脚本内表达式可以使用的地方都可以调用自定义函数。
调取函数时,调取函数输入的参数,在被调函数内,使用其的“拷贝”值,不影响该参数调取函数的继续使用;
在被调函数内定义的变量,在调取函数中也可以使用;想要避免该情况,将该变量在被调函数声明时作为形参进行声明即可。
一个简单的例子:
[root@localhost ~]# echo 123 |awk -f fun-test.awk
call fun_test: with test parameter.
name: TEST
[root@localhost ~]# cat fun-test.awk
function fun_test(name)
{
print "name:",name
}
{
print "call fun_test: with test parameter."
fun_test("TEST")
}
·其他函数:
getline函数:
getline和next类似都是读取下一行,但是,有不同点:
next:读取下一行后,返回输入循环首语句;
getline:读取下一行,程序继续进行,不会返回循环首语句。
[root@localhost ~]# awk -f getline-test.awk grade.log
ann 80 78 90 56
[root@localhost ~]# cat getline-test.awk
/steve/{
getline
print $0
}
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
使用getline读取文件和管道输入:
[root@localhost ~]# echo |awk -f getline-input.awk
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
root :0 2012-12-03 22:05
[root@localhost ~]# cat getline-input.awk
{
while(getline < "grade.log" > 0)
print
"who"|getline me
print me
close("who")
}
system函数:
[root@localhost ~]# awk -f getfile.awk
please input file name:grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
cat end.
[root@localhost ~]# cat getfile.awk
BEGIN{
printf "please input file name:"
getline < "-"
file=$0
system("cat " file)
print "cat end."
}
print输出重定向到文件和管道:
一个简单的例子:
[root@localhost ~]# awk -f printfile.awk
please input file name:grade.log
grade.log
cat filename end.
file: grade.log word count:
10
[root@localhost ~]# cat printfile.awk
BEGIN{
printf "please input file name:"
getline < "-"
file=$0
print file >"filename"
system("cat filename")
print "cat filename end."
print "file:",file,"word count:"
print file |"wc -c"
}
参考资料:
sed & awk:Doughherty & Robbins.
------------
·模式:
开始-主输入循环-结束
·主输入循环:模式匹配-记录-字段
·变量表达的字段:
[root@localhost ~]# echo a b c|awk 'BEGIN {one=1;two=2} {print $(one + two)}'
c
·-f选项:
[root@localhost ~]# awk -f list.awk name.log
andy,3233
steve,77899
[root@localhost ~]# cat list.awk
BEGIN { FS = " " }
{print $1 "," $2}
[root@localhost ~]# cat name.log
andy 3233
steve 77899
·分割符:
两个连续的分隔符间的字段值为空串。
·多个分隔符:(使用正则表达式表示)
[root@localhost ~]# awk -F "[:,]" '{print $1,$3}' name.log
andy xx
steve yy
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
·awk中对于变量赋值,空格为字符串间的连接操作符。
·模式匹配+算术运算:
使用awk,对于空行进行计数的脚本:
[root@localhost ~]# awk -f null_row.awk name.log
2
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
end,0:z
[root@localhost ~]# cat null_row.awk
/^$/ {
++x
}
END {
print x
}
·算术运算:
求取平均值脚本:
[root@localhost ~]# awk -f avg_grade.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat avg_grade.awk
{
total = $2 + $3 + $4 + $5
avg = total / 4
print $1,avg
}
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
·系统变量
FS:输入字段分割符
OFS:输出字段分割符
RS:输入记录分隔符
ORS:输出记录分割符
NF:当前记录中字段的总数
NR:当前的记录数
FILENAME:当前输入处理的文件名
·横跨处理多行记录
[root@localhost ~]# awk -f multi_row.awk multi_row.log
andy steve 678-888
lucy lee 890-777
[root@localhost ~]# cat multi_row.log
andy steve
hangzhou
789 street
678-888
lucy lee
hangzhou
301 street
890-777
[root@localhost ~]# cat multi_row.awk
BEGIN {
FS = "\n"
RS = ""
}
{ print $1,$NF }
·关系操作符(主要用于模式匹配)
大于-等于-小于-匹配-不匹配:
等于的例子:
[root@localhost ~]# awk -F "[:,]" 'NF == 3 {print $1}' name.log
andy
steve
end
[root@localhost ~]# cat name.log
andy,3233:xx
steve,77899:yy
end,0:z
匹配的例子:
[root@localhost ~]# awk -F "[:,]" '$1 ~ /andy/ {print $1,$3}' name.log
andy xx
·逻辑(布尔)操作符
逻辑或-与-非
与的例子:
[root@localhost ~]# awk -F "[:,]" '$1 ~ /andy/ && $2 == 3233 {print $1,$2}' name.log
andy 3233
·格式化打印
print:打印字符串和字段,自动在句末加入回车;
printf:格式化输出,不会在句末自动加入回车,需要明确指定“\n”
[root@localhost ~]# awk '{printf "|%-10s|%3d\n",$1,$2}' grade.log
|andy | 86
|lily | 66
|lucy | 77
|steve | 82
|ann | 80
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
·向awk脚本传递参数(变量one、two)
[root@localhost ~]# awk -f var_input.awk one=1 two=2 grade.log
87 80
67 72
78 80
83 80
81 80
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat var_input.awk
{
$2 += one
$3 += two
print $2,$3
}
另外一种获取方法:(使用-v选项,POSIX awk支持)
[root@localhost ~]# awk -v one=1 -v two=2 -f var_input.awk grade.log
87 80
67 72
78 80
83 80
81 80
#####进阶部分#####
·条件语句(基本上合C语言语法类似,下同)
一个例子:计算平均分,并显示为等级:
[root@localhost ~]# awk -f gtoclass.awk grade.log
andy 79.75 C
lily 62.75 D
lucy 70.00 C
steve 75.75 C
ann 76.00 C
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat gtoclass.awk
{
total = $2 + $3 + $4 + $5
avg = total / ( NF -1 )
if (avg >= 90) class = "A"
else if (avg >= 80) class = "B"
else if (avg >= 70) class = "C"
else if (avg >= 60) class = "D"
else class = "E"
printf "%-10s%5.2f%5s\n",$1,avg,class
}
·循环语句
for while do-while
求平均值的另外一种方法:
[root@localhost ~]# awk -f for_avg.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat for_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg = total / (NF - 1)
print $1,avg
}
使用while时的类似方法:
[root@localhost ~]# awk -f while_avg.awk grade.log
andy 79.75
lily 62.75
lucy 70
steve 75.75
ann 76
[root@localhost ~]# cat while_avg.awk
{
total = 0
i = 2
while ( i <= NF )
{
total += $i
i += 1
}
avg = total / (NF - 1)
print $1,avg
}
可以参考的一个综合的求阶乘的例子:
[root@localhost ~]# ./fact
enter number:5
the fact of 5 is 120
[root@localhost ~]# cat fact
awk '
BEGIN {
printf "enter number:"
}
$1 ~ /^[0-9]+$/ {
number = $1
if ( number == 0 )
fact = 1
else
fact = number
for ( x = number - 1;x > 1;x-- )
fact *= x
printf "the fact of %d is %g \n",number,fact
exit
}
{printf "invalid.enter number again:"}
' -
·影响程序流控制的语句
break:作用于循环语句,跳出循环
continue:作用于循环语句,跳出,进入下一个循环
next:作用于主输入循环,读取下一行输入行,返回到脚本顶部
exit:作用于主输入循环,退出主输入循环,将控制转移给END规则
·数组
选用NR作为数组下标的例子:
[root@localhost ~]# cat array_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg[NR] = total / (NF - 1)
}
END {
for ( x = 1;x <= NR;x++ )
class_avg_total += avg[x]
class_avg = class_avg_total / NR
for ( x = 1;x <=NR;x++ )
if ( avg[x] >= class_avg )
++above_avg
else
++below_avg
print "class avg:",class_avg
print "above avg:",above_avg
print "below avg:",below_avg
}
[root@localhost ~]# awk -f array_avg.awk grade.log
class avg: 72.85
above avg: 3
below avg: 2
·关联数组
数组的下标可以为字符串或数值
可以用于构造类似Python中的字典数据结构。
进行关联数组访问时,其输出数组条目顺序是随机的。
使用关联数组进行达到分数等级的个数的一个例子,综合以上各个内容:
[root@localhost ~]# awk -f fin_array_avg.awk grade.log
andy 79.75 C
lily 62.75 D
lucy 70 C
steve 75.75 C
ann 76 C
class avg: 72.85
above avg: 3
below avg: 2
C: 4
D: 1
[root@localhost ~]# cat fin_array_avg.awk
{
total = 0
for ( i =2; i <= NF; ++i )
total += $i
avg_arr[NR] = total / (NF - 1)
avg = avg_arr[NR]
if (avg >= 90) class = "A"
else if (avg >= 80) class = "B"
else if (avg >= 70) class = "C"
else if (avg >= 60) class = "D"
else class = "E"
++class_arr[class]
print $1,avg,class
}
END {
for ( x = 1;x <= NR;x++ )
class_avg_total += avg_arr[x]
class_avg = class_avg_total / NR
for ( x = 1;x <=NR;x++ )
if ( avg_arr[x] >= class_avg )
++above_avg
else
++below_avg
print "class avg:",class_avg
print "above avg:",above_avg
print "below avg:",below_avg
for ( class_x in class_arr )
print class_x ":",class_arr[class_x] | "sort"
}
·split进行数组创建
[root@localhost ~]# echo 2 |awk -f split_month.awk
2 II
[root@localhost ~]# cat split_month.awk
BEGIN {
split("I,II,III,IV,V",numb,",")
}
$1 > 0 && $1 <= 5 {
print $1,numb[$1]
exit
}
{
print "valid number."
exit
}
·多维数组
模拟引用多维数组
简单的例子:
BEGIN {
for (i = 1;i <= 2; ++i)
for ( j = 1; j <=2; ++j)
bitmap[i,j] = "O"
}
...
·系统变量数组
ARGV:awk+附带的参数(-f参数除外)组成的数组,下标从0开始;
ARGC:参数数组个数。
·函数
算术函数:
三角函数-对数函数-平方根函数-随机函数-取整函数
举例如下:
[root@localhost ~]# awk -f int_func.awk
33.3333
33
[root@localhost ~]# cat int_func.awk
BEGIN {
print 100/3
print int(100/3)
exit
}
字符串函数:
gsub(r,s,t):在t中将r匹配到所有字符串,匹配为s ;(t未输入时,默认为$0)
sub(r,s,t):在t中将r首次匹配到字符串,匹配为s ;(t未输入时,默认为$0)
index(s,t):返回t在s中的位置;否则返回0;
match(s,r):返回正则表达式r在s中的起始位置;否则返回0;
substr(s,p,n):返回s中p位置之后的那个字符;(n未输入时,返回p之后剩余的字符)
split(s,a,sep):将s根据sep分割后写入数组a中,返回数组元素个数;
length(s):返回s的长度;(s未输入时,默认为$0)
sprintf(“fmt”,expr)对于expr使用fmt格式说明
tolower(s):大写转化为小写
toupper(s):小写转化为大写
一些例子:
index和substr综合:
将第一个单词的首字符变为大写:
[root@localhost ~]# echo abc |awk -f index_substr.awk
Abc
[root@localhost ~]# cat index_substr.awk
BEGIN {
upper="ABCDEFGH"
lower="abcdfegh"
}
{
firstchar=substr($1,1,1)
if (charplace = index(lower,firstchar))
$1 = substr(upper,charplace,1)substr($1,2)
print $0
}
替换函数gsub和sub:
gsub的正则表达式替换,&为复制模式字符,\为转义符:(基本规则类似sed)
[root@localhost ~]# echo abc|awk '{gsub(/ab/,"\\start & end\\",$1);print $1}'
\start ab end\c
另外一个例子:
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
[root@localhost ~]# cat sub_gsub.awk
awk '
{
gsub(/"/,"")
if (sub(/an/,"An")) print
if (sub(/li/,"Li")) print
}' $*
[root@localhost ~]# ./sub_gsub.awk grade.log
Andy 86 78 99 56
Lily 66 70 59 56
Ann 80 78 90 56
match函数:
函数两个系统变量:RSTART,RLENGTH;
RSTART:匹配子串的开始位置;此为返回值,不匹配时,返回为0
RLENGTH:匹配字符串的字符数。
如使用match进行正则表达式的字符大小匹配,不同awk版本的实现不一致;
遇到不区分大小写的情况,如下:
[root@localhost ~]# cat test.awk
/[a-z]/{
print $0
}
[root@localhost ~]# echo ABC|awk -f test.awk
ABC
[root@localhost ~]# echo abc|awk -f test.awk
abc
[root@localhost ~]# echo 123|awk -f test.awk
[root@localhost ~]#
自定义函数:
在脚本的模式规则定义之前声明;
在脚本内表达式可以使用的地方都可以调用自定义函数。
调取函数时,调取函数输入的参数,在被调函数内,使用其的“拷贝”值,不影响该参数调取函数的继续使用;
在被调函数内定义的变量,在调取函数中也可以使用;想要避免该情况,将该变量在被调函数声明时作为形参进行声明即可。
一个简单的例子:
[root@localhost ~]# echo 123 |awk -f fun-test.awk
call fun_test: with test parameter.
name: TEST
[root@localhost ~]# cat fun-test.awk
function fun_test(name)
{
print "name:",name
}
{
print "call fun_test: with test parameter."
fun_test("TEST")
}
·其他函数:
getline函数:
getline和next类似都是读取下一行,但是,有不同点:
next:读取下一行后,返回输入循环首语句;
getline:读取下一行,程序继续进行,不会返回循环首语句。
[root@localhost ~]# awk -f getline-test.awk grade.log
ann 80 78 90 56
[root@localhost ~]# cat getline-test.awk
/steve/{
getline
print $0
}
[root@localhost ~]# cat grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
使用getline读取文件和管道输入:
[root@localhost ~]# echo |awk -f getline-input.awk
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
root :0 2012-12-03 22:05
[root@localhost ~]# cat getline-input.awk
{
while(getline < "grade.log" > 0)
"who"|getline me
print me
close("who")
}
system函数:
[root@localhost ~]# awk -f getfile.awk
please input file name:grade.log
andy 86 78 99 56
lily 66 70 59 56
lucy 77 78 69 56
steve 82 78 87 56
ann 80 78 90 56
cat end.
[root@localhost ~]# cat getfile.awk
BEGIN{
printf "please input file name:"
getline < "-"
file=$0
system("cat " file)
print "cat end."
}
print输出重定向到文件和管道:
一个简单的例子:
[root@localhost ~]# awk -f printfile.awk
please input file name:grade.log
grade.log
cat filename end.
file: grade.log word count:
10
[root@localhost ~]# cat printfile.awk
BEGIN{
printf "please input file name:"
getline < "-"
file=$0
print file >"filename"
system("cat filename")
print "cat filename end."
print "file:",file,"word count:"
print file |"wc -c"
}
参考资料:
sed & awk:Doughherty & Robbins.
相关推荐
**awk学习笔记与实例解析** awk 是一种强大的文本分析工具,尤其在Linux和Unix系统中广泛使用。它允许用户通过模式匹配和处理规则对输入数据进行操作,特别适合于处理结构化的文本文件,如日志文件、配置文件等。本...
### PDF电子书《Awk学习笔记2010修改版》相关知识点 #### AWK简介 AWK是一种强大的脚本语言,由Alfred V. Aho、Peter J. Weinberger和Brian W. Kernighan在1977年设计并实现。这三位计算机科学家的名字首字母合成了...
### awk学习笔记精要 #### 1. awk简介 awk是一种功能强大的文本处理语言,主要用于在Linux/Unix环境中处理文本和数据。它能够从标准输入、文件或其它命令的输出中提取并处理数据,支持自定义函数和动态正则表达式...
`awk`的学习需要结合实际案例进行,通过编写和运行脚本来熟悉其用法和功能。 总结,`awk`是Linux文本处理的重要工具,其灵活性和强大的功能使其在数据分析、日志分析等领域有着广泛的应用。通过深入学习和实践,...
### awk 学习笔记 #### 1. awk简介 awk是一种功能强大的文本处理语言,主要用于Linux和Unix环境下的数据处理。它可以处理来自标准输入、文件或命令输出的数据,支持自定义函数和动态正则表达式等功能,使其成为...
`awk` 是一种强大的文本分析工具,常用于处理和解析结构化的文本文件,如日志文件、配置文件等。在Linux和Unix系统中,`awk` ...通过不断地实践和学习,你将能够有效地利用 `awk` 解决日常工作中遇到的文本处理问题。
本笔记将详细介绍AWK的基本概念、语法、命令选项以及常用的特性。 ### 1. AWK简介 AWK是由三位开发者的首字母命名的——Alfred V. Aho、Peter J. Weinberger和Brian W. Kernighan。它是一种内置了多种功能的语言,...
本笔记主要涵盖了AWK的基础知识和高级特性,旨在帮助读者理解和掌握这一实用工具。 **一.1 什么是AWK?** AWK是由Aho、Weinberger和Kernighan三位计算机科学家开发的,它的名字就是由他们的姓氏首字母组成的。AWK是...
awk是一种强大的文本分析工具,广泛应用于Linux和Unix系统中。...学习awk能够极大地提升在Linux和Unix环境下处理文本数据的能力。通过深入理解和实践,你可以利用awk解决各种数据处理挑战,提高工作效率。
AWK是一种编程语言,用于在Linux环境下对文本和数据进行处理和分析。它是许多UNIX系统中的标准工具,并且是文本处理的强大工具。AWK通过模式匹配来处理文本文件,其中可以指定一系列规则,称为模式和动作,来对输入...
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和 动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。...
sed与awk(第二版)学习笔记
1. awk简介 2. awk命令格式和选项 2.1. awk的语法有两种形式 2.2. 命令选项 3. 模式和操作 3.1. 模式 3.2. 操作 4. awk的环境变量 5. awk运算符 6. 记录和域 6.1. 记录 6.2. 域 6.3. 域分隔符 7. gawk专用...
sed awk 学习笔记 SED 是一个“非交互式”的面向字符流的编辑器,它可以在一个地方指定所有的编辑指令,然后通过文件传递一次来执行他们。但是它在每次多于一行的处理能力方面有限制。SED 的优点是可以批量处理文件...
文件名`awk学习-20101008.doc`可能包含了作者在2010年10月8日整理的awk学习笔记,涵盖了基本语法、常用命令和实战案例。可能包括以下内容: 1. **基本语法**:介绍awk的基本结构,如模式-动作对,以及如何指定输入...