UNIT37 awk Integrated case

filename为以下文件,第二列用“-”隔开,以避免与FS冲突

ID   Name      Age City Country Tel              Salary  Children

1001 Steven    25  NY   U.S.A   +01-02-323222    $4900   2

1002 Huang-Yu  30  BJ   CHN     +86-10-36789966  $6000   1

1003 Fish-Mad  27  SG   SG      +65-67456632     $3000   3

1004 Vale-Kiss 46  LD   ENG    +44-20-87634321   $6280   3

.无pattern的action实例

awk ‘{print NR $1 $NF}’ data.txt 打印行号,第一列和最后一列,中间无分隔符

awk ‘{print $1,$NF}’ data.txt 打印第一列和最后一列,并且中间有分隔符

awk ‘{print $0,$NF+10}’ data.txt 打印整行,并打印最后一行加上10的结果

.有pattern的action实例

awk ‘/[0-9]/’ data.txt 打印记录中任意列包含数字0-9的行

awk ‘/01/||/02/’ data.txt 打印包含01或者02的行

awk ‘/01/,/02/’ data.txt 打印既包含01又包含02的行;等同awk ‘/01/&&/02’

awk ‘$1= =1001{print $2}’ data.txt 打印符合第一列等于1001的第二列

awk ‘$2= =”Steven”{print}’data.txt 打印符合第二列等于Steven的那些行

awk ‘$3>20&&$3<30’ data.txt 打印第三列在20到30之间的那些行

nawk ‘$3*$NF<100’ data.txt 打印第三列和最后一列乘积小于100的那些行

awk ‘$6~/01/{print $2}’ data.txt 打印符合仅仅第六列里包含01那些行的第二列

awk ‘NR>3{print $1,$2}’ data.txt 从第四行才开始打印第一列和第二列

.有BEGIN.END并包含FS.OFS的实例

awk –F”+” ‘{print $1}’ data.txt 按+为分隔符来分隔列,并打印第一列

gawk –F’[+\t$]’ ‘{print $6,$7,$8,$9}’data.txt 按+或\t或$都可作分隔符,并打印指定列

gawk ‘BEGIN{FS=”[\t+$]”}{print $6,$8,$9}’data.txt

按+,\t,$(顺序无所谓)为分割符,并打印指定列

gawk ‘BEGIN{FS=”[\t+$]”;OFS=”%”}{print $6,$7,$8,$9}’ data.txt

按+,\t,$为分割符,用%作输出分隔符打印指定列

gawk –F‘[ [ ] ]’ ‘{print $1}’ data.txt 按 [ 或 ]为分隔符,并打印第一列

gawk –F‘[ ][ ]’ ‘{print $1}’  data.txt 按[ 或 ] 为分隔符,并打印第一列

关于-F和BEGIN内的FS定义特别注意如下:

-F参数后紧跟单个分隔符,则用双引号“”,例如 –F”+”

-F参数后紧跟多个分隔符,则用单引号‘ ’并用[ ],中间顺序无所谓,例如-F’[+$]’

BEGIN中的FS无论是单个还是多个分隔,均用双引号“”,多个则需加[ ]

例如:nawk ‘BEGIN{FS=”[\t+$]”}{print $6,$8,$9}’data.txt

BEGIN中若同时有FS和OFS,则建议中间用分号“;”来分隔开,否则提示出错

例如:nawk ‘BEGIN{FS=”[\t+$]”;OFS=”%”}{print $6,$7,$8,$9}’ data.txt

半方括号[ ]也可以作为分隔符,顺序无所谓。例如:-F‘[[]]’ 或 –F‘[][]’

在用多个分隔符的时候,为避免语法错误或想得到正确的结果,最好用nawk

.条件if else和for while循环实例

gawk '{print($3>25?$2"old":$2"yong")}' data.txt $3>25显某某old否某某young

awk '{if($1>1002)print $2;else print $3}' data.txt若$2>1002打印$2否则打印$3

awk 'NR>1{if($3<30)print $2;else if($3<40)print $2"--m";else exit;}END{print 10}' data.txt从第二行开始判断,$3<30打印$2,30<$3 <40打印$2--m,都不符合就退出处理行,但是END后的操作仍执行

awk 'BEGIN{ORS=""}{for(i=1;i<NF-2;i++) print $i"\t"}{print "\n"}' data.txt

打印出每行的前面几列,最后几列不打印。特别注意:默认情况下,print每执行一次时,另起一行打印。因此为避免每打印一列就重新一行,设置ORS为空,但是在每打印完符合条件的所有列后,需要手工换行(循环外的print起此作用)。

awk 'BEGIN{ORS=""}{i=1;while(i<NF-2){print $i"\t";i++}}{print "\n"}' data.txt

功能同上,打印出每行的前面几列,最后几列不打印。

.数学运算和字符串操作实例

gawk ‘{print 2^5+sin(2.1)+int(0.9)}’ data.txt 在每一行都打印运算值(32.8632)

awk ‘END{print length(“How are you?”)}’ data.txt 打印出字符串的长度(12)

awk ‘END{print index(“How are you?”,”you”)}’ data.txt 返回you在字符串中的开始位置(9)

gawk ‘{gsub(/ \$/,””);print $0}’ data.txt 把每行的$符号用空替掉,并打印行

awk ‘END{print substr(“How are you?”,9,3)}’ data.txt

从字符串的第九个位置开始截出后面3个长度的子字符串

gawk ‘{print toupper($2), tolower($2)}’ data.txt

分别打印第二列大写和小写

gawk ‘END{print match(“How are you you?”,/you/),RSTART,RLENGTH}’ data.txt

打印you在字符串中第一个匹配的位置以及长度(9,9,3)

gawk ‘END{str=”How are you doing?”;sub(/o/,”0”,str);print str}’ data.txt

将字符串变量指定字符中第一个符合含有o的用0替换调

特别注意:sub函数的第三个参数不可直接用字符串,而必须用字符串变量。

awk ‘END{print split(“Jan,Feb,Mar,Apr,May”,mymonths,”,”),mymonths[2]}’ data.txt

将字符串用第三个参数分隔符号进行分隔,把分隔的各个元素放在第二个参数的数组中,函数返回分隔得到的元素数目。结果:(5,Feb)

.数组与关联数组(a[1],a[$1] a[$0],a[b[i]])

awk ‘{for(i=1;i<NF;i++) {a[i]=$i; print a[i]}}’ data.txt 把每一列按行打印

awk ‘{a[$1]=$2}END{for(x in a) print a[x]}’ data.txt

数组a关联到第一列,并将第二列值赋给a,最后打印a中的所有内容。注意:但不是顺序打印。for中的x是随意变量,awk自动确定。

awk ‘{b[i]=$1;a[$1]=$2;i++}END{for(j=1;j<i;j++) print b[j],a[b[j]]}’ data.txt

实现从第二行开始打印每一行的第一列和第二列的功能。

注意:i从0开始取值,而j从1开始。a为关联数组,b为顺序数组。

.多输入文件和NR.FNR的实例

a. awk ‘BEGIN{OFS=FS=”:”} NR==FNR{a[$1]=$2} NR>FNR{$2=a[$1];print}’ /etc/shadow /etc/passwd

该语句中第一个模式匹配到第一个输入文件shadow,第二个模式匹配到第二个输入文件passwd,并使用关联数组,实现不同文件关联列的其他列值相互替换。

A.awk对多输入文件的执行顺序是,先将代码作用于第一个文件(一行行读入),然后该重复的代码又作用于第二个文件,再作用于第三个文件。

B.awk对多输入文件的执行顺序产生了行序号的问题。当第一个文件执行完,下次读入第二个文件,那么第二个文件的第一行怎么算呢?如果又计为1的话,那不就两个1了么?(因为第一个文件也有第一行)。这就是NR和FNR的问题。

NR :全局行数(第二个文件的第一行接着第一个文件尾行数顺序计数)

FNR:当前文件自身的行数(不考虑前几个输入文件的自身行数及总数)

例如:data1.txt中有40行,data2.txt中有50行,那么awk ‘{}’ data1.txt data2.txt

NR 的值依次为:1,2……40,41,42……90

FNR的值依次为:1,2……40, 1, 2……50

.重定向输出和特别函数getline实例

awk ‘{print FILENAME,$0}’ data1.txt data2.txt >data_all.txt

把第一个文件和第二个文件合并到data_all.txt中,新文件第一列为原始文件名,后面列为原始文件内容。

awk ‘$1!=fd{close(fd);fd=$1} {print substr($0,index($0,“ ”)+1)>$1}’ data_all.txt

把合并后的新文件data.txt重新拆开成原来的两个子文件,依照新文件的第一列来产生新文件名。生成一个完整子文件后,关闭之;再生成下一个子文件。

gawk ‘BEGIN{system(“echo \”input your name:\” ”);getline var; print “\nYour name is”,d,”\n”}’

系统提示输入名字,然后将输入的名字打印出来。特别注意:该awk语句后没有输入文件名,而是利用键盘输入作为文件名。

A.getline从整体上来说,应这么理解它的用法:

当其左右无重定向符 | 或 < 时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量 var 或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。

当其左右有重定向符 | 或 < 时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:

gawk ‘BEGIN{“cat data.txt”|getline d; print d}’ data2.txt

gawk ‘BEGIN{“cat data.txt”|getline; print $0}’ data2.txt

gawk ‘BEGIN{getline d < “data.txt”; print d}’ data2.txt

gawk ‘BEGIN{getline < “data.txt”; print $0}’ data2.txt

以上四行代码均实现“只打印data.txt文件的第一行”(若打印全部行,用循环)

eg. nawk ‘BEGIN{FS=”:”;while(getline<”/etc/passwd”>0){print $1}}’ data.txt

gawk ‘{getline d; print d”#”$3}’ data.txt

awk首先读入第一行,接着处理getline函数,然后把下一行指定给变量d,再先打印d,由于d后面有换行符,所以后面紧跟的#会覆盖d,后面的$3同样也会覆盖d。

gawk ‘{getline; print $0”#”$3}’ data.txt

awk首先读入第一行接着处理getline函数,然后把下一行指定给$0,现在的$0已经是下一行内容,后面的#和$3(从$0中取)会覆盖$0的内容。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值