你好,游客 登录 注册 搜索
背景:
阅读新闻

awk命令实战详解

[日期:2017-01-09] 来源:Linux社区  作者:cooling88 [字体: ]

1. 生成数据报表

   有一个数据文件datafile是某位业务员的客户们3个月来的交易统计。datafile中的数据以冒号为分隔符,分了5个字段,分别为用户的name,电话phone,1月的消费金额,2月的消费金额,3月的消费金额,
  要求:(1)生成人可读的数据报表,格式清晰
        (2)生成每位客户(每行记录)的3个月的消费总数,以及每个月的总营业额;
    awk脚本:
report.awk
  1. #!/usr/bin/awk -f
  2. # 生成数据报表
  3. BEGIN {
  4. FS =":";
  5. OFS ="\t"
  6. print "\t\t Report tables"
  7. print "name\tphone\t\tJan\tFeb\tMar\t\tTotal"
  8. print "——————————————————————————————————————————————————————"
  9. }
  10. # 求客户3个月的业绩和
  11. {$6 = $3 + $4 + $5}
  12. #{printf "%-8s%-15s%-9s%-8s%-15s%-12s\n", $1,$2,$3,$4,$5,$6}
  13. {print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t\t"$6}
  14. {total3 +=$3}
  15. {total4 +=$4}
  16. {total5 +=$5}
  17. END {
  18. print "_______________________________________________________"
  19. print "This is Jan total: " total3
  20. print "This is Feb total: " total4
  21. print "This is Mar total: " total5
  22. }
  1. [root@web1 test]# awk -f report.awk datafile
  2. Report tables
  3. name phone JanFebMarTotal
  4. ——————————————————————————————————————————————————————
  5. M H (424)2222233299242332322332863
  6. N H (423)223424234532422323819
  7. N J (334)19923322343424232434800
  8. _______________________________________________________
  9. This is Jan total:878
  10. This is Feb total:37726
  11. This is Mar total:332878
 
2. awk 多文件联合处理
 
  2.1 用一个文件的域替换另一个文件的域
 
 系统用户文件passwd的第二段是用户密码,但是用X代替。真正的密码保存在shadow文件中的第二段。现在用shdow中的密文部分替换passwd中的x,生成一个新的passwd.pub
  1. vim join.awk
  2. # 替换文件的域
  3. BEGIN {
  4. # 指定输出分隔符
  5. OFS =":"
  6. # 输入字段分隔符
  7. FS =":"
  8. }
  9. # 执行体
  10. {
  11. if(NR <= FNR){# 正在处理第一个输入文件shadow
  12. a[$1]= $2
  13. }
  14. if(NR > FNR){# 正在处理第二个输入文件passwd
  15. $2 = a[$1]
  16. print
  17. }
  18. }
  1. awk -f join.awk /etc/shadow /etc/passwd > passwd.pub
 小结: NR 是awk正在工作中的记录数,FNR是awk的当前输入文件的记录数,一开始工作时,NR<FNR,随着输入记录的增多NR会超过FNR.
     
  awk内建变量的用法:
 eg.
 直接做判断
  1. # 执行体
  2. NR <= FNR {# 正在处理第一个输入文件shadow
  3. a[$1]= $2
  4. }
  5. NR > FNR {# 正在处理第二个输入文件passwd
  6. $2 = a[$1]
  7. # 输出一整条记录==print $0
  8. print
  9. }
 
3. 检验passwd格式的正确性
不合法的情况可能有:
 (1)记录域数量不为7
 (2)用户名违规,不包含任何字母或数字
 (3)未设置密码,(密码字段应该是x,而不是"*")
 
passwd.check.awk
  1. # check passwd
  2. BEGIN {
  3. FS =":"
  4. }
  5. # 执行体
  6. NF !=7{ // 引用内建变量NF 做判断
  7. printf("line %d, does not have 7 fields: %s\n", NR, $0)
  8. }
  9. $1 !~/[a-zA-Z0-9]/{ // !~ 不匹配正则
  10. printf("line %d, non alpha and nnumeric user id: %s\n", NR, $0)
  11. }
  12. $2 =="*"{ // == 语法类似于C语言
  13. printf("line %d, no password: %s\n", NR, $0)
  14. }
 
1. 生成数据报表
   有一个数据文件datafile是某位业务员的客户们3个月来的交易统计。datafile中的数据以冒号为分隔符,分了5个字段,分别为用户的name,电话phone,1月的消费金额,2月的消费金额,3月的消费金额,
  要求:(1)生成人可读的数据报表,格式清晰
        (2)生成每位客户(每行记录)的3个月的消费总数,以及每个月的总营业额;
    awk脚本:
report.awk
  1. #!/usr/bin/awk -f
  2. # 生成数据报表
  3. BEGIN {
  4. FS =":";
  5. OFS ="\t"
  6. print "\t\t Report tables"
  7. print "name\tphone\t\tJan\tFeb\tMar\t\tTotal"
  8. print "——————————————————————————————————————————————————————"
  9. }
  10. # 求客户3个月的业绩和
  11. {$6 = $3 + $4 + $5}
  12. #{printf "%-8s%-15s%-9s%-8s%-15s%-12s\n", $1,$2,$3,$4,$5,$6}
  13. {print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t\t"$6}
  14. {total3 +=$3}
  15. {total4 +=$4}
  16. {total5 +=$5}
  17. END {
  18. print "_______________________________________________________"
  19. print "This is Jan total: " total3
  20. print "This is Feb total: " total4
  21. print "This is Mar total: " total5
  22. }
  1. [root@web1 test]# awk -f report.awk datafile
  2. Report tables
  3. name phone JanFebMarTotal
  4. ——————————————————————————————————————————————————————
  5. M H (424)2222233299242332322332863
  6. N H (423)223424234532422323819
  7. N J (334)19923322343424232434800
  8. _______________________________________________________
  9. This is Jan total:878
  10. This is Feb total:37726
  11. This is Mar total:332878
 
2. awk 多文件联合处理
 
  2.1 用一个文件的域替换另一个文件的域
 
 系统用户文件passwd的第二段是用户密码,但是用X代替。真正的密码保存在shadow文件中的第二段。现在用shdow中的密文部分替换passwd中的x,生成一个新的passwd.pub
  1. vim join.awk
  2. # 替换文件的域
  3. BEGIN {
  4. # 指定输出分隔符
  5. OFS =":"
  6. # 输入字段分隔符
  7. FS =":"
  8. }
  9. # 执行体
  10. {
  11. if(NR <= FNR){# 正在处理第一个输入文件shadow
  12. a[$1]= $2
  13. }
  14. if(NR > FNR){# 正在处理第二个输入文件passwd
  15. $2 = a[$1]
  16. print
  17. }
  18. }
  1. awk -f join.awk /etc/shadow /etc/passwd > passwd.pub
 小结: NR 是awk正在工作中的记录数,FNR是awk的当前输入文件的记录数,一开始工作时,NR<FNR,随着输入记录的增多NR会超过FNR.
     
  awk内建变量的用法:
 eg.
 直接做判断
  1. # 执行体
  2. NR <= FNR {# 正在处理第一个输入文件shadow
  3. a[$1]= $2
  4. }
  5. NR > FNR {# 正在处理第二个输入文件passwd
  6. $2 = a[$1]
  7. # 输出一整条记录==print $0
  8. print
  9. }
 
 
3. 检验passwd格式的正确性
不合法的情况可能有:
 (1)记录域数量不为7
 (2)用户名违规,不包含任何字母或数字
 (3)未设置密码,(密码字段应该是x,而不是"*")
 
passwd.check.awk
  1. # check passwd
  2. BEGIN {
  3. FS =":"
  4. }
  5. # 执行体
  6. NF !=7{ // 引用内建变量NF 做判断
  7. printf("line %d, does not have 7 fields: %s\n", NR, $0)
  8. }
  9. $1 !~/[a-zA-Z0-9]/{ // !~ 不匹配正则
  10. printf("line %d, non alpha and nnumeric user id: %s\n", NR, $0)
  11. }
  12. $2 =="*"{ // == 语法类似于C语言
  13. printf("line %d, no password: %s\n", NR, $0)
  14. }

Linux常用命令之awk http://www.linuxidc.com/Linux/2016-09/135046.htm

Linux系统之文本格式化工具awk http://www.linuxidc.com/Linux/2016-02/128150.htm

AWK简介及使用实例 http://www.linuxidc.com/Linux/2013-12/93519.htm

Linux awk文本分析工具 http://www.linuxidc.com/Linux/2015-12/126217.htm

Linux文本处理工具之awk  http://www.linuxidc.com/Linux/2015-01/111437.htm

如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm

文本分析工具-awk  http://www.linuxidc.com/Linux/2014-12/110939.htm

AWK入门基础教程  http://www.linuxidc.com/Linux/2016-12/138138.htm

使用awk格式化输出文本 http://www.linuxidc.com/Linux/2016-04/130193.htm

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-01/139374.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款