awk 高级编程
cat awk.txt
user1 password1 username1 unit1 10
user2 password2 username2 unit2 20
user3 password3 username3 unit3 30
[root@store_1 shell]# awk '{ if($5>20) print $0}' awk.txt
user3 password3 username3 unit3 30 #大于
[root@store_1 shell]# awk '{ sum+=$5} END {print sum}' awk.txt
60                                 #累加
[root@store_1 shell]# awk '{ if(($5=5)||($5=20)) print $0}' awk.txt
user1 password1 username1 unit1 5
user2 password2 username2 unit2 5
user3 password3 username3 unit3 5  #错误判断式,双等号
[root@store_1 shell]# awk '{ if(($5==5)||($5==20)) print $0}' awk.txt
user2 password2 username2 unit2 20  #正确判断
[root@store_1 shell]# awk '{ if(($5==5)||($5==20)) { print $0 }}' awk.txt
user2 password2 username2 unit2 20 #加大括号{}
 一个问题客户有一个用户列表,大概有2w用户,他有一个有趣的工作要做,就是把每个账户目录放
到特定的目录下,例如13910011234这个目录要放到139/10/这个目录下,从这里可以看出规律是
手机号码的前三位是二级目录名,手机的第3、4为是三级目录名。
#awk '{ printf "mv %s   %s/%s\n",$1,substr($1,1,3),substr($1,4,2) }' example3.txt
mv 13910011234   139/10
mv 15920312343   159/20
mv 13922342134   139/22
mv 15922334422   159/22
mv 15922394422   159/22
脚本式awk
# cat awk.txt
user1 password1 username1 unit1 10
user2 password2 username2 unit2 20
user3 password3 username3 unit3 30
# cat awk.sh
#!/bin/awk -f
{
 sum+=$5
 if($1=="user1") {
   if($2=="password1") {
      if($4=="unit1") {
          print "user1 is ok"
      } else { print "not ok" }

   }
 }
}
END { print sum }
输出:
[root@store_1 shell]# awk -f awk.sh awk.txt
user1 is ok
60
经典例子1:
1、用某一文件的一个域替换另一个文件中的的特定域?
http://bbs.chinaunix.net/forum/viewtopic.php?t=500015
文件passwd:
s2002408030068:x:527:527::/home/dz02/s2002408030068:/bin/pw
s2002408032819:x:528:528::/home/dz02/s2002408032819:/bin/pw
s2002408032823:x:529:529::/home/dz02/s2002408032823:/bin/pw
文件shadow:
s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:12676:0:99999:7:::
s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:12676:0:99999:7:::
s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:12676:0:99999:7:::
用shadow文件中的密文部分替换passwd中的"x",生一个新passwd文件,如下所示
s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:527:527::/home/dz02/s2002408030068:/bin/pw
s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:528:528::/home/dz02/s2002408032819:/bin/pw
s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:529:529::/home/dz02/s2002408032823:/bin/pw
CODE:
# awk 'BEGIN{OFS=FS=":"} NR==FNR{a[$1]=$2}NR>FNR{$2=a[$1];print}' shadow passwd
s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:527:527::/home/dz02/s2002408030068:/bin/pw
s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:528:528::/home/dz02/s2002408032819:/bin/pw
s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:529:529::/home/dz02/s2002408032823:/bin/pw
NR==FNR,第一个文件shadow,以$1为下标,将$2的值赋给数组a
NR>FNR,第二个文件passwd,将文件shadow$2的值赋值给文件passwd
也可以用如下命令代替:
# awk 'BEGIN{OFS=FS=":"} NR==FNR{a[$1]=$2;next}{$2=a[$1];print}' shadow passwd
s2002408030068:$1$d8NwFclG$v4ZTacfR2nsbC8BnVd3dn1:527:527::/home/dz02/s2002408030068:/bin/pw
s2002408032819:$1$UAvNbHza$481Arvk1FmixCP6ZBDWHh0:528:528::/home/dz02/s2002408032819:/bin/pw
s2002408032823:$1$U2eJ3oO1$bG.eKO8Zupe0TnyFhWX9Y.:529:529::/home/dz02/s2002408032823:/bin/pw


经典例子2:
cat file1:
0011AAA 200.00 20050321
0012BBB 300.00 20050621
0013DDD 400.00 20050622
0014FFF 500.00 20050401
cat file2:
I0011  11111
I0012  22222
I0014  55555
I0013  66666
规则:比较 file1的1-4字符 和 file2的2-5 字符,如果相同,将file2 的第二列 与 file1 合并 file3
0011AAA 200.00 20050321 11111
0012BBB 300.00 20050621 22222
0013DDD 400.00 20050622 66666
0014FFF 500.00 20050401 55555
code:
# awk 'NR==FNR{a[substr($1,2,4)]=$2;next}{$4=a[substr($1,1,4)];print}' file2 file1
0011AAA 200.00 20050321 11111
0012BBB 300.00 20050621 22222
0013DDD 400.00 20050622 66666
0014FFF 500.00 20050401 55555
也可以用如下命令:
# awk 'NR==FNR{a[substr($1,2,4)]=$2}NR>FNR{$4=a[substr($1,1,4)];print}' file2 file1
0011AAA 200.00 20050321 11111
0012BBB 300.00 20050621 22222
0013DDD 400.00 20050622 66666
0014FFF 500.00 20050401 55555
经典例子3:
file3文件内容
  1     0.5  100
                                10  15    36.5
file4文件
  50   10    9
                                3.2   1     5
将两个文件合成一个文件如:
  51     10.5    109
                                                             13.2   16      41.5
就是对应的字段进行相加以后的数字。
# awk '{for(i=1;i<=NF;i++) a[i]=$i;getline <"file4";for(i=1;i<=NF;i++) printf  a[i]+$i" ";printf "\n"}' file3
51 10.5 109
13.2 16 41.5
也可以使用如下命令:
# awk '{for (i=1;i<=NF;i++) a[i]=$i;getline <"file4";for (i=1;i<NF;i++) printf $i+a[i]" ";printf $NF+a[NF] "\n"}' file3
51 10.5 109
13.2 16 41.5
经典例子4--重定向
[root@store_1 shell]# cat xf
1       1       1
2       2       2       2
1       1       1
2       2       2       2
#awk '{if(NF==3) print $0 > 3;else print $0 > 2 }' xf  #定向后设备必须使用数字3,2
[root@store_1 shell]# cat 3  
1       1       1
1       1       1
经典例子5-netstat 状态统计
cmonitor:~# netstat -nt|awk '/^tcp/{++state[$NF]}END{for(i in state) printf "%s  %d\n",i,state[i]}'
SYN_RECV  19
TIME_WAIT  3
ESTABLISHED  1