首頁 > 軟體

awk命令實戰詳解

2020-06-16 17:23:47

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 "tt Report tables"
  7. print "nametphonettJantFebtMarttTotal"
  8. print "——————————————————————————————————————————————————————"
  9. }
  10. # 求客戶3個月的業績和
  11. {$6 = $3 + $4 + $5}
  12. #{printf "%-8s%-15s%-9s%-8s%-15s%-12sn", $1,$2,$3,$4,$5,$6}
  13. {print $1"t"$2"t"$3"t"$4"t"$5"tt"$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: %sn", NR, $0)
  8. }
  9. $1 !~/[a-zA-Z0-9]/{ // !~ 不匹配正則
  10. printf("line %d, non alpha and nnumeric user id: %sn", NR, $0)
  11. }
  12. $2 =="*"{ // == 語法類似於C語言
  13. printf("line %d, no password: %sn", 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 "tt Report tables"
  7. print "nametphonettJantFebtMarttTotal"
  8. print "——————————————————————————————————————————————————————"
  9. }
  10. # 求客戶3個月的業績和
  11. {$6 = $3 + $4 + $5}
  12. #{printf "%-8s%-15s%-9s%-8s%-15s%-12sn", $1,$2,$3,$4,$5,$6}
  13. {print $1"t"$2"t"$3"t"$4"t"$5"tt"$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: %sn", NR, $0)
  8. }
  9. $1 !~/[a-zA-Z0-9]/{ // !~ 不匹配正則
  10. printf("line %d, non alpha and nnumeric user id: %sn", NR, $0)
  11. }
  12. $2 =="*"{ // == 語法類似於C語言
  13. printf("line %d, no password: %sn", 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


IT145.com E-mail:sddin#qq.com