1.6 awk关系、布尔运算符、表达式
AWK的大部分运算符及其意义与C/C++、Java、Linux等相似,如:
< 小于
> 大于
<= 小于等于
>= 大于等于
== 等于
!= 不等于
|| 逻辑或
&& 逻辑与
! 逻辑非
+ 加
- 减
* 乘
/ 除
% 模
^或** 乘方
++x 在返回x值之前,x变量加1
x++ 在返回x值之后,x变量加1
AWK独有的运算符有:~ 匹配正则表达式、!~ 不匹配正则表达式。
awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd ~正则表达式为匹配字符串
awk 'BEGIN {FS=":"} {if($3==10||$4==10) print $0}' /etc/passwd ==是为数字匹配
awk 'BEGIN {FS=":"} {if($3~10||$4~10) print $0}' /etc/passwd 正则表达式~表示包含
awk执行文件:
#!/bin/awk -f
BEGIN {FS=","}
{ total=$4+$5+$6+$7+$8
avg=total/5
print $1,avg
}
与其他编程语言一样,awk表达式用于存储、操作和获取数据,一个awk表达式可由数值、字符常量、变量、操作符、函数和正则表达式自由组合而成。
变量是一个值的标识符,定义awk变量非常方便,只需定义一个变量名并将值赋给它即可。变量名只能包含字母、数字和下划线,而且不能以数字开头,这与C/C++、Java的变量定义规范相同。
1.7 awk格式化输出:
awk的一大主要功能是产生报表,报表就要求按照预定的格式输出,awk借鉴C语言的语法,定义了printf输出语句,它可以规定输出的格式。
printf:printf (格式控制符,参数)
awk格式控制符及其意义如下:
- 左对齐
width 域的步长
.prec 小数点右边的位数
%c ASCII字符
%d 整型数
%e 浮点数,科学记数法
%f 浮点数
%o 八进制数
%s 字符串
%x 十六进制数
awk 'BEGIN {FS=","; print "NAME\t\tPHCHNUMBER"} {printf("%-15s\t%s\n",$1,$3)}' sturecord2
结果为:
NAME PHCHNUMBER
Li Hao 80283058
Zhang Ju 2343255
Wang Bin 2342353
Zhu Lin 23434
1.8 awk内置字符串函数
awk内置字符串函数极为强大,是Shell处理字符串的常用工具。常用的字符串函数如下:
sub(regular expression,substitution string);
sub(regular expression,substitution string,target string);
gsub(r,s) 在输入文件中用s替换r
gsub(r,s,t) 在t中用s替换r
index(s,t) 返回s中字符串第一个t的位置
length(s) 返回s的长度
match(s,t) 测试s是否包含匹配t的字符串
split(r,s,t) 在t上将r分成序列s
sub(r,s,t) 将t中第1次出现的r替换为s
substr(r,s) 返回字符串r中从s开始的后缀部分
substr(r,s,t) 返回字符串r中从s开始长度为t的后缀部分
toupper(string)、tolower(string)以上两个函数分别返回参数字符串的大写和小写的形式。
variable = sprintf("string with format specifiers ",expr1,expr2,...)
该函数和printf的差别等同于C语言中printf和sprintf的差别。前者将格式化后的结果输出到输出流,而后者输出到函数的返回值中。
systime()该函数返回当前时间距离1970年1月1日之间相差的秒数。
strftime()时间格式化函数,其格式化规则等同于C语言中的strftime函数提供的规则:
数据格式含义
%a Abbreviated weekday name
%A Full weekday name
%b Abbreviated month name
%B Full month name
%c Date and time representation appropriate for locale
%d Day of month as decimal number (01 – 31)
%H Hour in 24-hour format (00 – 23)
%I Hour in 12-hour format (01 – 12)
%j Day of year as decimal number (001 – 366)
%m Month as decimal number (01 – 12)
%M Minute as decimal number (00 – 59)
%p Current locale's A.M./P.M. indicator for 12-hour clock
%S Second as decimal number (00 – 59)
%U Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w Weekday as decimal number (0 – 6; Sunday is 0)
%W Week of year as decimal number, with Monday as first day of week (00 – 53)
%x Date representation for current locale
%X Time representation for current locale
%y Year without century, as decimal number (00 – 99)
%Y Year with century, as decimal number
/> awk 'BEGIN{ print strftime("%D",systime())}'
11/15/11
/> awk 'BEGIN{ now = strftime("%T"); print now}'
23:17:29
常用的内置数学函数如下:
atan2(x,y) y,x范围内的余切
cos(x) 余弦函数
exp(x) 求幂
int(x) 取整
log(x) 自然对数
sin(x) 正弦函数
sqrt(x) 平方根
/> awk 'BEGIN{print 31/3}'
10.3333
/> awk 'BEGIN{print int(31/3)}'
10
AWK还支持用户自定义函数。用户自定义函数可以放在awk脚本的任何可以放置模板和动作的地方。
方法如下:
function methodName(parameter1,parameter2,...) {
//statements
//return expression
}
给函数中本地变量传递值只使用变量的拷贝。数组通过地址或者指针传递,所以可以在函数内部直接改变数组元素的值。
函数内部使用的任何没有作为参数传递的变量都被看做是全局变量,也就是这些变量对于整个程序都是可见的。如果变量在函数中发生了变化,那么就是在整个程序中发生了改变。
唯一向函数提供本地变量的办法就是把他们放在参数列表中,这些参数通常被放在列表的最后。如果函数调用没有提供正式的参数,那么参数就初始化为空。return语句通常就返回程序控制并向调用者返回一个值。
/> cat grades
20 10
30 20
40 30
/> cat add.sc
function add(first,second) {
return first + second
}
{ print add($1,$2) }
/> awk -f add.sc grades
30
50
70
1.9 awk条件语句和循环语句
awk条件语句和循环语句与C语言的语法完全一样.
if (条件表达式)
动作1
[else
动作2]
while (条件表达式)
动作
do
动作
while (条件表达式)
for (设置计数器初值;测试计数器;计数器变化)
动作
awk中还提供了一种special for的循环,见如下声明:
for (item in arrayname) {
print arrayname[item]
}
1.10 awk数组
数组是用于存储一系列值的变量,这些值之间通常是有联系的,可通过索引来访问数组的值,索引需要用中括号括起,数组的基本格式为:
array[index]=value
关联数组是指数组的索引可以是字符串,也可以是数字。关联数组在索引和数组元素值之间建立起关联,对每一个数组元素,awk自动维护了一对值:索引和数组元素值。关联数组的值无需以连续的地址进行存储,awk的所有数组都是关联数组。
字符串和数字之间的差别是明显的,如,我们使用array[09]指定一个数组值,如果换成array[9]就不能指定到与array[09]相同的值。
由于awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储。
数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。
/> cat employees
Tom Jones 4424 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
/> awk '{name[x++] = $2}; END{for (i = 0; i < NR; i++) print i, name[i]}' employees
0 Jones
1 Adams
2 Chang
3 Black
在上例中,数组name的下标是变量x。awk初始化该变量的值为0,在每次使用后自增1,读取文件中的第二个域的值被依次赋值给name数组的各个元素。在END模块中,for循环遍历数组的值。因为下标是关键字,所以它不一定从0开始,可以从任何值开始。
#这里是用内置变量NR作为数组的下标了。
/> awk '{id[NR] = $3}; END {for (x = 1; x <= NR; x++) print id[x]}' employees
4424
5346
1654
1683
再如: /> cat db
Tom Jones
Mary Adams
Sally Chang
Billy Black
Tom Savage
Tom Chung
Reggie Steel
Tommy Tucker
/> awk '/^Tom/{name[NR]=$1}; END {for(i = 1;i <= NR; i++) print name[i]}' db
Tom
Tom
Tom
Tommy
从输出结果可以看出,只有匹配正则表达式的记录的第一个域被赋值给数组name的指定下标元素。因为用NR作为下标,所以数组的下标不可能是连续的,因此在END模块中用传统的for循环打印时,不存在的元素就打印空字符串了。下面我们看看用special for的方式会有什么样的输出。
/> awk '/^Tom/{name[NR]=$1};END{for(i in name) print name[i]}' db
Tom
Tom
Tommy
Tom
下面我们看一下用字符串作为下标的例子:(如果下标是字符串文字常量,则需要用双引号括起来)
/> cat testfile2
tom
mary
sean
tom
mary
mary
bob
mary
alex
/> awk '/tom/{count["tom"]++}; /mary/{count["mary"]++}; END{print "There are " count["tom"] \
" Toms and " count["mary"] " Marys in the file."} testfile2
There are 2 Toms and 4 Marys in the file.
在上例中,count数组有两个元素,下标分别为tom和mary,每一个元素的初始值都是0,没有tom被匹配的时候,count["tom"]就会加一,count["mary"]在匹配mary的时候也同样如此。END模块中打印出存储在数组中的各个元素。
/> awk '{count[$1]++}; END{for(name in count) printf "%-5s%d\n",name, count[name]}' testfile2
mary 4
tom 2
alex 1
bob 1
sean 1
在上例中,awk是以记录的域作为数组count的下标。
/> awk '{count[$1]++; if (count[$1] > 1) name[$1]++}; END{print "The duplicates were "; for(i in name) print i}' testfile2
The duplicates were
mary
tom
在上例中,如count[$1]的元素值大于1的时候,也就是当名字出现多次的时候,一个新的数组name将被初始化,最后打印出那么数组中重复出现的名字下标。
之前我们介绍的都是如何给数组添加新的元素,并赋予初值,现在我们需要介绍一下如何删除数组中已经存在的元素。要完成这一功能我们需要使用内置函数delete,见如下命令:
/> awk '{count[$1]++}; \
END{for(name in count) {\
if (count[name] == 1)\
delete count[name];\
} \
for (name in count) \
print name}' testfile2
mary
tom
上例中的主要技巧来自END模块,先是变量count数组,如果数组中某个元素的值等于1,则删除该元素,这样等同于删除只出现一次的名字。最后用special for循环打印出数组中仍然存在的元素下标名称。
最后我们来看一下如何使用命令行参数数组,见如下命令:
/> awk 'BEGIN {for(i = 0; i < ARGC; i++) printf("argv[%d] is %s.\n",i,ARGV[i]); printf("The number of arguments, ARGC=%d\n",ARGC)}' testfile "Peter Pan" 12
argv[0] is awk.
argv[1] is testfile.
argv[2] is Peter Pan.
argv[3] is 12.
The number of arguments, ARGC=4
从输出结果可以看出,命令行参数数组ARGV是以0作为起始下标的,命令行的第一个参数为命令本身(awk),这个使用方式和C语句main函数完全一致。
/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"
ARGV[2] is bob
bob
awk: (FILENAME=testfile2 FNR=9) fatal: cannot open file `bob' for reading (No such file or directory)
先解释一下以上命令的含义,name变量被赋值为命令行的第三个参数,即bob,之后再在输入文件中找到匹配该变量值的记录,并打印出该记录。
在输出的第二行报出了awk的处理错误信息,这主要是因为awk将bob视为输入文件来处理了,然而事实上这个文件并不存在,下面我们需要做进一步的处理来修正这个问题。
/> awk 'BEGIN{name=ARGV[2]; print "ARGV[2] is " ARGV[2]; delete ARGV[2]}; $1 ~ name{print $0}' testfile2 "bob"
ARGV[2] is bob
bob
从输出结果中我们可以看到我们得到了我们想要的结果。需要注意的是delete函数的调用必要要在BEGIN模块中完成,因为这时awk还没有开始读取命令行参数中指定的文件。
相关推荐
### sed命令和awk编程教程知识点概述 #### 一、sed命令基本概念与使用方法 - **sed命令简介**: - `sed` 是一个非交互式的流编辑器(Stream Editor),主要用于自动化文本处理任务,尤其适合处理大型文件或者复杂的...
描述:“高效awk编程,高清文字版” 这里的描述向我们传达了这本书的目的和特色。首先,“高效”强调了效率和优化,意味着书中将教你如何编写出高效能的awk脚本。其次,“高清文字版”可能意味着这本书的电子版格式...
AWK是一种非常实用的编程语言,它在文本处理和数据分析方面表现出色。它的特点是编写程序非常简单,即便是只有一两行的程序也能完成复杂的任务。AWK非常适合那些需要快速解决特定数据处理问题的场景。 ### AWK程序...
在shell编程中,awk的灵活性和强大功能使其成为不可或缺的一部分。 1. **基本语法** awk的工作原理基于模式匹配和执行相应的动作。基本语法结构是 `awk 'pattern {action}' file`。pattern是匹配条件,action是...
2. **变量`$0`与`FS`**:在awk中,`$0`总是指代当前行,而`FS`是字段分隔符,决定数据是如何被切分的。默认情况下,`FS`为空白字符,但在处理复杂的数据格式时,如`/etc/passwd`文件中使用冒号(:)分隔,可以通过设置...
总结来说,awk 是一种强大的文本处理工具,通过模式匹配和自定义操作,可以高效地处理和解析文本数据。熟练掌握 awk,能帮助我们在处理大量文本信息时提高效率,尤其在系统管理和数据分析领域有着广泛的应用。
在处理文本时,awk允许自定义字段变量,以实现对字段的引用和操作,如`$1`、`$2`分别代表第一、第二字段。 ### sed sed(stream editor)是一个流编辑器,用于对文本进行过滤和转换。sed一次处理一行,可以执行...
《Effective awk Programming: Universal Text Processing and Pattern Matching》(第4版)是一本由Arnold Robbins编写的关于awk编程语言的专业指南。这本书不仅深入探讨了awk编程的核心概念,还提供了大量的实际...
根据您提供的文件内容,这里总结了关于awk的一些知识点。 ### 1. Awk概述 Awk是一种编程语言,用于处理文本模式和报告生成。它主要用于Linux操作系统,并广泛应用于UNIX Shell编程中。Awk按照记录和字段的方式来...
### Linux Shell 编程之 Awk 用法详解 在Linux环境下,Awk是一种强大的文本处理工具,用于处理结构化的数据。Awk不仅能够执行基本的打印操作,还能进行复杂的模式匹配、数据筛选和数学运算,是Linux系统管理员和...
### AWK编程语言知识点概述 #### 一、AWK编程语言简介 - **起源与开发者**:AWK编程语言最初由Alfred Aho、Brian Kernighan和Peter Weinberger于1977年开发。 - **特点**:AWK是一种模式匹配语言,用于编写...
2. **简单易用**:相较于C语言等编程语言,AWK的语法更为简洁,使得开发过程更加高效。AWK提供了从简单的命令行工具到复杂的程序设计语言的解决方案,用户可以根据问题的复杂程度选择合适的工具。 3. **易于获取**...
Linux中的`awk`是一个强大的文本分析工具...总结,`awk`是Linux文本处理的重要工具,其灵活性和强大的功能使其在数据分析、日志分析等领域有着广泛的应用。通过深入学习和实践,我们可以充分利用`awk`来提高工作效率。