翼度科技»论坛 云主机 LINUX 查看内容

Awk实战案例精讲

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
Awk实战案例精讲

插入几个新字段

在"a b c d"的b后面插入3个字段e f g。
  1. echo a b c d|awk '{$3="e f g "$3}1'
复制代码
格式化空白

移除每行的前缀、后缀空白,并将各部分左对齐。
  1.       aaaa        bbb     ccc                 
  2.    bbb     aaa ccc
  3. ddd       fff             eee gg hh ii jj
复制代码
  1. awk 'BEGIN{OFS="\t"}{$1=$1;print}' a.txt
复制代码
执行结果:
  1. aaaa    bbb     ccc
  2. bbb     aaa     ccc
  3. ddd     fff     eee     gg      hh      ii      jj
复制代码
筛选IPv4地址

从ifconfig命令的结果中筛选出除了lo网卡外的所有IPv4地址。
  1. ## 1.法一:
  2. ifconfig | awk '/inet / && !($2 ~ /^127/){print $2}'
  3. # 按段落读取
  4. ## 2.法二:
  5. ifconfig | awk 'BEGIN{RS=""}!/lo/{print $6}'
  6. ## 3.法三:
  7. ifconfig |\
  8. awk '
  9.   BEGIN{RS="";FS="\n"}
  10.   !/lo/{$0=$2;FS=" ";$0=$0;print $2;FS="\n"}
  11. '
复制代码
读取.ini配置文件中的某段
  1. [base]
  2. name=os_repo
  3. baseurl=https://xxx/centos/$releasever/os/$basearch
  4. gpgcheck=0
  5. enable=1
  6. [mysql]
  7. name=mysql_repo
  8. baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch
  9. gpgcheck=0
  10. enable=1
  11. [epel]
  12. name=epel_repo
  13. baseurl=https://xxx/epel/$releasever/$basearch
  14. gpgcheck=0
  15. enable=1
  16. [percona]
  17. name=percona_repo
  18. baseurl = https://xxx/percona/release/$releasever/RPMS/$basearch
  19. enabled = 1
  20. gpgcheck = 0
复制代码
  1. awk '
  2.     BEGIN{RS=""}  # 按段落
  3.     /\[mysql\]/{
  4.         print;
  5.         while( (getline)>0 ){
  6.             if(/\[.*\]/){
  7.                 exit
  8.             }
  9.             print
  10.         }
  11. }' a.txt
复制代码
根据某字段去重

去掉uid=xxx重复的行。
  1. 2019-01-13_12:00_index?uid=123
  2. 2019-01-13_13:00_index?uid=123
  3. 2019-01-13_14:00_index?uid=333
  4. 2019-01-13_15:00_index?uid=9710
  5. 2019-01-14_12:00_index?uid=123
  6. 2019-01-14_13:00_index?uid=123
  7. 2019-01-15_14:00_index?uid=333
  8. 2019-01-16_15:00_index?uid=9710
复制代码
  1. awk -F"?" '!arr[$2]++{print}' a.txt
复制代码
结果:
  1. 2019-01-13_12:00_index?uid=123
  2. 2019-01-13_14:00_index?uid=333
  3. 2019-01-13_15:00_index?uid=9710
复制代码
次数统计
  1. portmapper
  2. portmapper
  3. portmapper
  4. portmapper
  5. portmapper
  6. portmapper
  7. status
  8. status
  9. mountd
  10. mountd
  11. mountd
  12. mountd
  13. mountd
  14. mountd
  15. nfs
  16. nfs
  17. nfs_acl
  18. nfs
  19. nfs
  20. nfs_acl
  21. nlockmgr
  22. nlockmgr
  23. nlockmgr
  24. nlockmgr
  25. nlockmgr
复制代码
  1. awk '
  2.   {arr[$1]++}
  3.   END{
  4.     OFS="\t";
  5.     for(idx in arr){printf arr[idx],idx}
  6.   }
  7. ' a.txt
复制代码
统计TCP连接状态数量
  1. $ netstat -tnap
  2. Proto Recv-Q Send-Q Local Address   Foreign Address  State       PID/Program name
  3. tcp        0      0 0.0.0.0:22      0.0.0.0:*        LISTEN      1139/sshd
  4. tcp        0      0 127.0.0.1:25    0.0.0.0:*        LISTEN      2285/master
  5. tcp        0     96 192.168.2.17:22 192.168.2.1:2468 ESTABLISHED 87463/sshd: root@pt
  6. tcp        0      0 192.168.2017:22 192.168.201:5821 ESTABLISHED 89359/sshd: root@no
  7. tcp6       0      0 :::3306         :::*             LISTEN      2289/mysqld
  8. tcp6       0      0 :::22           :::*             LISTEN      1139/sshd
  9. tcp6       0      0 ::1:25          :::*             LISTEN      2285/master
复制代码
统计得到的结果:
  1. 5: LISTEN
  2. 2: ESTABLISHED
复制代码
  1. netstat -tnap |\
  2. awk '
  3.     /^tcp/{
  4.         arr[$6]++
  5.     }
  6.     END{
  7.         for(state in arr){
  8.             print arr[state] ": " state
  9.         }
  10.     }
  11. '
复制代码
一行式:
  1. netstat -tna | awk '/^tcp/{arr[$6]++}END{for(state in arr){print arr[state] ": " state}}'
  2. netstat -tna | /usr/bin/grep 'tcp' | awk '{print $6}' | sort | uniq -c
复制代码
统计日志中各IP访问非200状态码的次数

日志示例数据:
  1. 111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169
复制代码
统计非200状态码的IP,并取次数最多的前10个IP。
  1. # 法一
  2. awk '
  3.   $8!=200{arr[$1]++}
  4.   END{
  5.     for(i in arr){print arr[i],i}
  6.   }
  7. ' access.log | sort -k1nr | head -n 10
  8. # 法二:
  9. awk '
  10.     $8!=200{arr[$1]++}
  11.     END{
  12.         PROCINFO["sorted_in"]="@val_num_desc";
  13.         for(i in arr){
  14.             if(cnt++==10){exit}
  15.             print arr[i],i
  16.         }
  17. }' access.log
复制代码
统计独立IP

​     url     访问IP       访问时间      访问人
  1. a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
  2. b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest
  3. c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest
  4. a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
  5. a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest
  6. b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest
复制代码
需求:统计每个URL的独立访问IP有多少个(去重),并且要为每个URL保存一个对应的文件,得到的结果类似:
  1. a.com.cn  2
  2. b.com.cn  2
  3. c.com.cn  1
复制代码
并且有三个对应的文件:
  1. a.com.cn.txt
  2. b.com.cn.txt
  3. c.com.cn.txt
复制代码
代码:
  1. BEGIN{
  2.   FS="|"
  3. }
  4. !arr[$1,$2]++{
  5.   arr1[$1]++
  6. }
  7. END{
  8.   for(i in arr1){
  9.     print i,arr1[i] >(i".txt")
  10.   }
  11. }
复制代码
输出第二字段重复的所有整行

如下文本内容
  1. 1 zhangsan
  2. 2 lisi
  3. 3 zhangsan
  4. 4 lisii
  5. 5 a
  6. 6 b
  7. 7 c
  8. 8 d
  9. 9 a
  10. 10 b
复制代码
问题1:输出第二列重复的所有整行,即输出结果:
  1. 1 zhangsan
  2. 3 zhangsan
  3. 5 a
  4. 9 a
  5. 6 b
  6. 10 b
复制代码
代码:
  1. awk '{
  2.     arr[$2]++;
  3.     if(arr[$2]>1){
  4.       if(arr[$2]==2){
  5.         print first[$2]
  6.       };
  7.       print $0
  8.     }else{
  9.       first[$2]=$0
  10.     }
  11. }' a.txt
复制代码
问题2:输出第二列不重复的所有整行,即输出结果:
  1. 2 lisi
  2. 4 lisii
  3. 7 c
  4. 8 d
复制代码
代码:
  1. awk '{
  2.    arr[$2]++
  3.    first[$2]=$0
  4. }
  5. END{
  6.    for(i in arr){
  7.      if(arr[i]==1){print first[i]}
  8.    }
  9. }' a.txt
复制代码
相邻重复行去重,并保留最后一行

根据字段进行比较,去除相邻的重复行,并保留重复行中的最后一行以及那些非重复行。
a.log内容:
  1. TCP 10.33.4.149:19404 wrr
  2. -> 10.27.4.197:19404 FullNat 10 2 0
  3. TCP 10.33.4.150:19039 wrr
  4. TCP 10.33.4.150:19089 wrr
  5. -> 10.27.4.201:19089 FullNat 10 2 0
  6. TCP 10.33.4.150:19094 wrr
  7. TCP 10.33.4.150:19102 wrr
  8. TCP 10.33.4.150:19107 wrr
  9. -> 10.27.100.150:19107 FullNat 10 18 0
  10. TCP 10.33.4.150:19111 wrr
  11. TCP 10.33.4.150:19112 wrr
  12. TCP 10.33.4.150:19113 wrr
  13. TCP 10.33.4.150:19114 wrr
  14. TCP 10.33.4.150:19207 wrr
  15. -> 10.27.100.150:19207 FullNat 10 18 0
复制代码
以第一字段判断重复,去重相邻行,最终输出结果:
  1. TCP 10.33.4.149:19404 wrr
  2. -> 10.27.4.197:19404 FullNat 10 2 0
  3. TCP 10.33.4.150:19089 wrr
  4. -> 10.27.4.201:19089 FullNat 10 2 0
  5. TCP 10.33.4.150:19107 wrr
  6. -> 10.27.100.150:19107 FullNat 10 18 0
  7. TCP 10.33.4.150:19207 wrr
  8. -> 10.27.100.150:19207 FullNat 10 18 0
复制代码
方案:
[code]# 用第一个字段比较。如果想按其他字段比较,换成$N,N为对应的字段号awk '{  if($1!=prev){    a[++n]=$0;  }else{    a[n]=$0  }}{prev=$1}END{  for(i=1;i

举报 回复 使用道具