gawk是 GNU的awk,具有很强的文本处理功能
awk对文本处理有很强的功能,对于文字档里的资料进行修改比对抽取
gawk主要功能是对档案的每一行搜寻指定的patterns,当一行有符合指定的patterns,gawk就会在此一行执行被指定的actions
gawk有很多patterns和action组成,action在大括号里面,一个pattern后面跟一个action
pattern {action}
pattern和action可以同时被省略,但是不能同时被省略
pattern省略,对于每一行action都会执行
action省略,内定action会打印出来所有符合pattern的输入行
执行gawk程序
#直接执行
gawk 'program' Input-file1 input-file2...
#程序写入文件
gawk -f program-file input-file1 input-file2...
#一个例子
gawk '/foo/ {print $0}' bbs-list.txt
#/foo/ 为pattern,搜寻输入档的每一行是否含有子字符串'foo'
#print $0表示将现在的这一行内容输出,$0表示整行
#另外一个例子
gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shiped
#$1表示文件的第一个栏位,$2和$3表示第二和第三个栏位
#END表示在所有的输入读完之后,执行一次print sum的动作```
###读取输入档案
gawk的输入可以从标准输入或者指定档案中提取
一般,一个记录为一行,字段之间以空格符分隔
gawk会把输入分解为记录,默认是一行,内建变量RS 默认值是”\n”
内建变量FNR会储存目前输入档案已经被读取的记录数
NR会储存目前为止所有输入档案已经被读取的记录数“`
字段
#字段之间默认是以空格符分开的
#$NF表示一个记录的最后一个栏位
#NF是内建变量,表示目前这个记录的栏位个数
gawk '$1~/foo/ {print $0}' bbs-list.txt
#$1~/foo/表示将每个记录的第一个字段做检查,如果含有foo,这个字段将会被输出
#gawk使用field separator将记录分解为字段,内建变量FS表示
#使用 = 来改变FS的值
gawk 'BEGIN {FS=","}; {print $2}'
#BEGIN后面的action会在第一个记录被读取之前执行一次
#执行上面的后会等待输出```
###输出
print输出,更复杂的格式使用printf
print item1, item2…各个item之间会有空白分开,最后有一个换行符
直接print会输出一个record
要打印出空白行 print “”
打印文字 print “hello world”
Output Separators
可以使用任何字符串作为item之间的分隔,output field sepatator
OFS来设定,print输出完了之后会输出一个output record separator
ORS 默认值是 “\n” 换行
gawk ‘BEGIN {OFS=”;”; ORS=”\n\n”} {print $1,$2}’ bbs-list.txt
printf
精确控制输出格式,指定item的输出宽度,还有数字格式
printf format, item1, item2,…
另外printf 不会自动换行
printf “%4s”,”foo”“`
patterns
只有pattern符合现在的输入记录,对应的action才会被执行
patterns的种类
/regular expression/
一个这个表达式被当成一个pattern,记录里面含有这个表达式就符合
expression
当一个值不为0或者一个字符串不是空的,就是符合
pat1,pat2
一对patterns以逗号分开,指定记录的范围
BEGIN
END
特别的pattern,在开始或者结束执行时,会执行其相对应的action
null
空pattern,对于每个输入记录都视为符合的pattern
/regular expression/
gawk '/foo/ {print $2}' bbs-list.txt
也可以使用比较
gawk '$1~/foo/ {print $0}' bbs-list.txt
gawk '$1!~/foo/ {print $0}' bbs-list.txt```
###比较算式
< <= > >= == !=
x~y表示x符合regular expression y 则结果是真
x!~y表示x不符合regular expression y 则结果为真“`
布尔运算的patterns
|| && !
gawk '/2400/ && /foo/' bbs-list.txt
gawk '/2400/ || /foo/' bbs-list.txt
gawk '!/foo/' bbs-list.txt```
###算式运算
- / % ^ **“`
条件算式
selector ? if-true-exp:if-false-exp```
###控制语句
if(condition) then-body [else else-body]
if(x%2==0)
print “x is seven”
else
print “x is odd”
写成gawk就是(要用大括号把语句括起来)
gawk ‘{x=3
if(x%2==0)
print “x is seven”
else
print “x is odd”}’
while
gawk ‘{i=1
while(i<=3){
print i
i++
}}’
do-while
gawk ‘{i=1
do{
print i
i++
}while(i<=10)
}’
for
gawk ‘{for(i-1;i<=3;i++)
print i}’
break
break 会跳出循环的最内层
gawk ‘{num=$1
for(div=2;div*div<=num;div++)
if(num%div==0)
break
if(num%div!=0)
printf “Smallest divsor of %d is %d \n”,num,div
else
printf “%d is prime\n”,num}’
continue
gawk ‘BEGIN{
for(x=0;x<=20;x++){
if(x==5)
continue
printf(“%d”,x)
}
print ” “
}’
next,next file,exit
next 强迫立刻停止处理目前记录继续下一个记录
next file 停止处理目前的文件
exit 使得程序停止然后跳出,但是会执行END的action“`
内建函数
index(str,find)
在字符串str里面,寻找find第一次出现的位置
length(string)
match(string,regexp)
寻找符合reg最长最靠左边的子字符串的index值
sprintf(format,exp1...)
sub(regrxp,replacement,target)
gsub(regexp,replacement,target)
寻找所有的符合地方,加以替换
substr(string,start,length)
tolower(string)
toupper(string)```
###输入输出的内建函数
close(filename)
system(command)
允许使用执行系统命令,执行完后回到gawk
BEGIN {system(“ls”)}“`
定义函数
function name(parameter-list){
body-of-function
}
{print "sum=",SquareSum($1,$2)}
function SquareSum(x,y){
sum=x*x+y*y
return sum
}```
###实例
NF表示栏位(字段个数)
FS表示字段间的间隔符,默认为空格
NR表示现在文件已经被读取的行数
FNR表示新打开一个文件,行数值就会从0开始计算
OFS表示列输出间隔符
gawk ‘{if(NF>max) max=NF}
END {print max}’
gawk ‘length($0)>80’
这里会采用内定的print
gawk ‘NF>0’
将文件中所有空白行删除,因为只输出非空白行
gawk ‘{if(NF>0) print}’
对至少有一个字段的所有行,输出
gawk ‘BEGIN {for(i=1;i<=7;i++)
print int(101*rand())}’
输出0到100的7个随机值
ll -h | gawk ‘{x+=$5}; END {print “total Mbytes:” x}’
cat file | gawk ‘{if(x<length()) x=length()} END {print “maximum line length is “,x}’
gawk ‘BEGIN {FS=”:”} {print $1|”sort”}’ /etc/passwd
gawk ‘{nlines++} END {print nlines}’
打印一个文件的总行数
gawk ‘END {print NR}’
打印总行数
gawk ‘{print NR,$0}’
类似于cat -n“`