AWK工具使用学习笔记(二)
?
一、AWK操作符:
1、给域命名。 给域取一个有意义的名字,更利于记忆。
tom@svr:~/ssh$ awk '{name=$1;belts=$4;if(belts ~/Yellow/) print name" is belt "
belts }' grade.txt
P.Bunny is belt Yellow
注意点:a 用分号分隔不同的定义语句; b 变量可以直接输出,但原样输出的字符串则必须用引号。
?
tom@svr:~/ssh$ awk '{name=$1;belts=$4 if(belts ~/Yellow/) print name "is belt " blets }' grade.txt
awk: line 1: syntax error at or near if? 缺少分号
?
?
2、修改数据域的取值。
修改M.Tansley的目前级别分域,使其数值从40减为39
?awk '{name=$1;score=$6; if(name~/M.Tansley/) score=score-1; print name "\t" score}' grade.txt
会输出其他的行
tom@svr:~/ssh$ awk '{name=$1;score=$6; if(name=="M.Tansley") {score=score-1; print name "\t" score} } ' grade.txt
M.Tansley?????? 39
tom@svr:~/ssh$
只会输出当前行。区别:后者将score减1和打印动作框起来作为if模式的动作;而前者中只有score减1是if模式的动作,打印动作属于缺省动作。
?
3、只显示修改的记录。
tom@svr:~/ssh$ awk '{name=$1;score=$6; if(name=="M.Tansley") {score=score-1; print name "\t" score} } ' grade.txt
M.Tansley?????? 39
tom@svr:~/ssh$
?
4、新增列
tom@svr:~/ssh$ awk 'BEGIN {print "Name??? Difference\n--------------------------"} {if($6<$7) {dif=$7-$6; print $1,dif} }' grade.txt
Name??? Difference
--------------------------
M.Tansley 4
J.Lulu 2
tom@svr:~/ssh$
注意与 awk 'BEGIN {print "Name??? Difference\n--------------------------"} {if($6<$7) dif=$7-$6; print $1,dif }' grade.txt 的区别。dif赋值只在$6<$7满足的前提下执行,而print则为缺省执行。
?
二、AWK内置的字符串函数
1)gsub??????? 查找与替换,相当于sed
格式gsub(/目标模式/,/替换模式/,范围) 第三个参数可以省略,若省略则表示在$0范围内查找与替换。
例:将学号为4842的字段替换成4800.
tom@svr:~/ssh$ awk 'gsub(/4842/,4800) {print $0}' grade.txt
J.Troll???????? 07/99?? 4800??? Brow-3? 12????? 26????? 26
tom@svr:~/ssh$
?
2)length???? 返回长度
例:在末尾返回名字域的字符串长度。
tom@svr:~/ssh$ awk '{len=length($1); {print $0,len}}' grade.txt
M.Tansley?????? 05/99?? 48311?? Green?? 8?????? 40????? 44 9
J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26 6
P.Bunny???????? 02/99?? 48????? Yellow? 12????? 35????? 28 7
J.Troll???????? 07/99?? 4842??? Brow-3? 12????? 26????? 26 7
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28 9
tom@svr:~/ssh$
?
3)index????? 返回目标字符串的第一位置
例:返回字符串P.Bunny中第一个出现ny的位置。
tom@svr:~/ssh$ awk 'BEGIN {ind=index("P.Bunny","ny"); print ind} ' grade.txt
6
tom@svr:~/ssh$
?
4)match??? 是否包含目标字符
例子1: name域中含有L字母的行。
tom@svr:~/ssh$ awk '{name=$1; if(match(name,/L/)) {print $0} }' grade.txt
J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
tom@svr:~/ssh$
例子2:name域中L字母打头的行。
tom@svr:~/ssh$ awk '{name=$1; if(match(name,/^L/)) {print $0} }' grade.txt
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
tom@svr:~/ssh$
例子3:name域中L出现的次数为1或者多次的行。
tom@svr:~/ssh$ awk '{name=$1; if(match(name,/L+/)) {print $0} }' grade.txt
J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
?
?
5)split??????? 将源字符用分隔符分成字符数组
第一个参数:指定被分割的字符串
第二个参数:指定数组名
第三个参数:指定分割符,必须用双引号,例如"." ,"-" ,"/" 等
tom@svr:~/ssh$ awk '{print split($4,myarr,"-")}' grade.txt
1
1
1
2
2
tom@svr:~/ssh$
?
6)sprint???? 格式输出
?
?
7)sub??????? 发现并替换模式的第一次出现位置
例:
tom@svr:~/ssh$ awk '{print $0}' grade.txt
M.Tansley?????? 05/99?? 48311?? Green?? 8?????? 40????? 44
J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26
P.Bunny???????? 02/99?? 48????? Yellow? 12????? 35????? 28
J.Troll???????? 07/99?? 4842??? Brow-3? 12???? ?26????? 26
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
tom@svr:~/ssh$ awk '{name=$1;if(name=="J.Troll")sub(/26/,50,$0); print $0 }' grade.txt
M.Tansley?????? 05/99?? 48311?? Green?? 8?????? 40????? 44
J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26
P.Bunny???????? 02/99?? 48????? Yellow? 12????? 35????? 28
J.Troll???????? 07/99?? 4842??? Brow-3? 12????? 50????? 26
L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
tom@svr:~/ssh$
?
?
8)substr?? 截取字符串,得到子串
例:
tom@svr:~/ssh$ awk '{fullname=$1;firstName=substr(fullname,3,99); print firstName "\t" $0}' grade.txt
Tansley M.Tansley?????? 05/99?? 48311?? Green?? 8?????? 40????? 44
Lulu??? J.Lulu????????? 06/99?? 48317?? green?? 9?????? 24????? 26
Bunny?? P.Bunny???????? 02/99?? 48????? Yellow? 12????? 35????? 28
Troll?? J.Troll???????? 07/99?? 4842??? Brow-3? 12????? 26????? 26
Tansley L.Tansley?????? 05/99?? 4712??? Brow-3? 12????? 30????? 28
tom@svr:~/ssh$
?
awk -F[:] '{print $1,$3,$4}' /etc/passwd?
使用特殊域分割符。