1. 程式人生 > >18個awk的經典實戰案例

18個awk的經典實戰案例


回到:

  • Linux系列文章
  • Shell系列文章
  • Awk系列文章

介紹

這些案例是我收集起來的,大多都是我自己遇到過的,有些比較經典,有些比較具有代表性。

這些awk案例我也錄了相關視訊的講解awk 18個經典實戰案例精講,歡迎大家去瞅瞅。

插入幾個新欄位

在"a b c d"的b後面插入3個欄位e f g

echo a b c d|awk '{$3="e f g "$3}1'

格式化空白

移除每行的字首、字尾空白,並將各部分左對齊。

      aaaa        bbb     ccc                 
   bbb     aaa ccc
ddd       fff             eee gg hh ii jj
awk 'BEGIN{OFS="\t"}{$1=$1;print}' a.txt

執行結果:

aaaa    bbb     ccc
bbb     aaa     ccc
ddd     fff     eee     gg      hh      ii      jj

篩選IPv4地址

從ifconfig命令的結果中篩選出除了lo網絡卡外的所有IPv4地址。

讀取.ini配置檔案中的某段

[base]
name=os_repo
baseurl=https://xxx/centos/$releasever/os/$basearch
gpgcheck=0

enable=1

[mysql]
name=mysql_repo
baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch

gpgcheck=0
enable=1

[epel]
name=epel_repo
baseurl=https://xxx/epel/$releasever/$basearch
gpgcheck=0
enable=1
[percona]
name=percona_repo
baseurl = https://xxx/percona/release/$releasever/RPMS/$basearch
enabled = 1
gpgcheck = 0

根據某欄位去重

去掉uid=xxx重複的行。

2019-01-13_12:00_index?uid=123
2019-01-13_13:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710
2019-01-14_12:00_index?uid=123
2019-01-14_13:00_index?uid=123
2019-01-15_14:00_index?uid=333
2019-01-16_15:00_index?uid=9710
awk -F"?" '!arr[$2]++{print}' a.txt

結果:

2019-01-13_12:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710

次數統計

portmapper
portmapper
portmapper
portmapper
portmapper
portmapper
status
status
mountd
mountd
mountd
mountd
mountd
mountd
nfs
nfs
nfs_acl
nfs
nfs
nfs_acl
nlockmgr
nlockmgr
nlockmgr
nlockmgr
nlockmgr
awk '{arr[$1]++}END{OFS="\t";for(idx in arr){printf arr[idx],idx}}' a.txt

統計TCP連線狀態數量

$ netstat -tnap
Proto Recv-Q Send-Q Local Address   Foreign Address  State       PID/Program name
tcp        0      0 0.0.0.0:22      0.0.0.0:*        LISTEN      1139/sshd
tcp        0      0 127.0.0.1:25    0.0.0.0:*        LISTEN      2285/master
tcp        0     96 192.168.2.17:22 192.168.2.1:2468 ESTABLISHED 87463/sshd: root@pt
tcp        0      0 192.168.2017:22 192.168.201:5821 ESTABLISHED 89359/sshd: root@no
tcp6       0      0 :::3306         :::*             LISTEN      2289/mysqld
tcp6       0      0 :::22           :::*             LISTEN      1139/sshd
tcp6       0      0 ::1:25          :::*             LISTEN      2285/master

統計得到的結果:

5: LISTEN
2: ESTABLISHED

一行式:

netstat -tna | awk '/^tcp/{arr[$6]++}END{for(state in arr){print arr[state] ": " state}}'
netstat -tna | /usr/bin/grep 'tcp' | awk '{print $6}' | sort | uniq -c

統計日誌中各IP訪問非200狀態碼的次數

日誌示例資料:

111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169 

統計非200狀態碼的IP,並取次數最多的前10個IP。

# 法一
awk '$8!=200{arr[$1]++}END{for(i in arr){print arr[i],i}}' access.log | sort -k1nr | head -n 10

# 法二:
awk '
    $8!=200{arr[$1]++}
    END{
        PROCINFO["sorted_in"]="@val_num_desc";
        for(i in arr){
            if(cnt++==10){exit}
            print arr[i],i
        }
}' access.log

統計獨立IP

​ url 訪問IP 訪問時間 訪問人

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest
c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest
a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

需求:統計每個URL的獨立訪問IP有多少個(去重),並且要為每個URL儲存一個對應的檔案,得到的結果類似:

a.com.cn  2
b.com.cn  2
c.com.cn  1

並且有三個對應的檔案:

a.com.cn.txt
b.com.cn.txt
c.com.cn.txt

程式碼:

處理欄位缺失的資料

ID  name    gender  age  email          phone
1   Bob     male    28   [email protected]     18023394012
2   Alice   female  24   [email protected]  18084925203
3   Tony    male    21                  17048792503
4   Kevin   male    21   [email protected]    17023929033
5   Alex    male    18   [email protected]    18185904230
6   Andy    female       [email protected]    18923902352
7   Jerry   female  25   [email protected]  18785234906
8   Peter   male    20   [email protected]     17729348758
9   Steven          23   [email protected]    15947893212
10  Bruce   female  27   [email protected]   13942943905

當欄位缺失時,直接使用FS劃分欄位來處理會非常棘手。gawk為了解決這種特殊需求,提供了FIELDWIDTHS變數。

FIELDWIDTH可以按照字元數量劃分欄位。

awk '{print $4}' FIELDWIDTHS="2 2:6 2:6 2:3 2:13 2:11" a.txt

處理欄位中包含了欄位分隔符的資料

下面是CSV檔案中的一行,該CSV檔案以逗號分隔各個欄位。

Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

需求:取得第三個欄位"1234 A Pretty Street, NE"。

當欄位中包含了欄位分隔符時,直接使用FS劃分欄位來處理會非常棘手。gawk為了解決這種特殊需求,提供了FPAT變數。

FPAT可以收集正則匹配的結果,並將它們儲存在各個欄位中。(就像grep匹配成功的部分會加顏色顯示,而使用FPAT劃分欄位,則是將匹配成功的部分儲存在欄位$1 $2 $3...中)。

echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'

取欄位中指定字元數量

16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

得到:

16  001
16  002
23  001
23  002
awk '{print $1,substr($2,1,3)}'
awk 'BEGIN{FIELDWIDTH="2 2:3"}{print $1,$2}' a.txt

行列轉換

name age
alice 21
ryan 30

轉換得到:

name alice ryan
age 21 30
awk '
    {
      for(i=1;i<=NF;i++){
        if(!(i in arr)){
          arr[i]=$i
        } else {
            arr[i]=arr[i]" "$i
        }
      }
    }
    END{
        for(i=1;i<=NF;i++){
            print arr[i]
        }
    }
' a.txt

行列轉換2

檔案內容:

74683 1001
74683 1002
74683 1011
74684 1000
74684 1001
74684 1002
74685 1001
74685 1011
74686 1000
....
100085 1000
100085 1001

檔案就兩列,希望處理成

74683 1001 1002 1011
74684 1000 1001 1002
...

就是隻要第一列數字相同, 就把他們的第二列放一行上,中間空格分開

{
  if($1 in arr){
    arr[$1] = arr[$1]" "$2
  } else {
    arr[$1] = $2
  }
  
}

END{
  for(i in arr){
    printf "%s %s\n",i,arr[i]
  }
}

篩選給定時間範圍內的日誌

grep/sed/awk用正則去篩選日誌時,如果要精確到小時、分鐘、秒,則非常難以實現。

但是awk提供了mktime()函式,它可以將時間轉換成epoch時間值。

# 2019-11-10 03:42:40轉換成epoch
$ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573328560

藉此,可以取得日誌中的時間字串部分,再將它們的年、月、日、時、分、秒都取出來,然後放入mktime()構建成對應的epoch值。因為epoch值是數值,所以可以比較大小,從而決定時間的大小。

下面strptime1()實現的是將2019-11-10T03:42:40+08:00格式的字串轉換成epoch值,然後和which_time比較大小即可篩選出精確到秒的日誌。

下面strptime2()實現的是將10/Nov/2019:23:53:44+08:00格式的字串轉換成epoch值,然後和which_time比較大小即可篩選出精確到秒的日誌。

BEGIN{
  # 要篩選什麼時間的日誌,將其時間構建成epoch值
  which_time = mktime("2019 11 10 03 42 40")
}

{
  # 取出日誌中的日期時間字串部分
  match($0,"^.*\\[(.*)\\].*",arr)
  
  # 將日期時間字串轉換為epoch值
  tmp_time = strptime2(arr[1])
  
  # 通過比較epoch值來比較時間大小
  if(tmp_time > which_time){
    print 
  }
}

# 構建的時間字串格式為:"10/Nov/2019:23:53:44+08:00"
function strptime2(str   ,dt_str,arr,Y,M,D,H,m,S) {
  dt_str = gensub("[/:+]"," ","g",str)
  # dt_sr = "10 Nov 2019 23 53 44 08 00"
  split(dt_str,arr," ")
  Y=arr[3]
  M=mon_map(arr[2])
  D=arr[1]
  H=arr[4]
  m=arr[5]
  S=arr[6]
  return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}

function mon_map(str   ,mons){
  mons["Jan"]=1
  mons["Feb"]=2
  mons["Mar"]=3
  mons["Apr"]=4
  mons["May"]=5
  mons["Jun"]=6
  mons["Jul"]=7
  mons["Aug"]=8
  mons["Sep"]=9
  mons["Oct"]=10
  mons["Nov"]=11
  mons["Dec"]=12
  return mons[str]
}

去掉/**/中間的註釋

示例資料:

/*AAAAAAAAAA*/
1111
222

/*aaaaaaaaa*/
32323
12341234
12134 /*bbbbbbbbbb*/ 132412

14534122
/*
    cccccccccc
*/
xxxxxx /*ddddddddddd
    cccccccccc
    eeeeeee
*/ yyyyyyyy
5642341

前後段落關係判斷

從如下型別的檔案中,找出false段的前一段為i-order的段,同時輸出這兩段。

2019-09-12 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-order',
  ],
]
2019-09-12 07:16:27 [-][
  'data' => [
    false,
  ],
]
2019-09-21 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-order',
  ],
]
2019-09-21 07:16:27 [-][
  'data' => [
    'http://192.168.100.20:2800/api/payment/i-user',
  ],
]
2019-09-17 18:34:37 [-][
  'data' => [
    false,
  ],
]
BEGIN{
  RS="]\n"
  ORS=RS
}
{
  if(/false/ && prev ~ /i-order/){
    print tmp
    print
  }
  tmp=$0
}

兩個檔案的處理

有兩個檔案file1和file2,這兩個檔案格式都是一樣的。

需求:先把檔案2的第五列刪除,然後用檔案2的第一列減去檔案一的第一列,把所得結果對應的貼到原來第五列的位置,請問這個指令碼該怎麼編寫?

file1:
50.481  64.634  40.573  1.00  0.00
51.877  65.004  40.226  1.00  0.00
52.258  64.681  39.113  1.00  0.00
52.418  65.846  40.925  1.00  0.00
49.515  65.641  40.554  1.00  0.00
49.802  66.666  40.358  1.00  0.00
48.176  65.344  40.766  1.00  0.00
47.428  66.127  40.732  1.00  0.00
51.087  62.165  40.940  1.00  0.00
52.289  62.334  40.897  1.00  0.00
file2:
48.420  62.001  41.252  1.00  0.00
45.555  61.598  41.361  1.00  0.00
45.815  61.402  40.325  1.00  0.00
44.873  60.641  42.111  1.00  0.00
44.617  59.688  41.648  1.00  0.00
44.500  60.911  43.433  1.00  0.00
43.691  59.887  44.228  1.00  0.00
43.980  58.629  43.859  1.00  0.00
42.372  60.069  44.032  1.00  0.00
43.914  59.977  45.551  1.00  0.00

相關推薦

小白福利貼:18Python爬蟲實戰案例(已開源)

加qq群813622576或vx:tanzhouyiwan免費獲取Python視訊教程以及各類PDF! 爬蟲小工具 downloader.py:檔案下載小助手 一個可以用於下載圖片、視訊、檔案的小工具,有下載進度顯示功能。稍加修改即可新增到自己的爬蟲中。 動

18Python爬蟲實戰案例(已開源)

目錄爬蟲小工具檔案下載小助手爬蟲實戰筆趣看小說下載VIP視訊下載百度文庫文章下載_rev1百度文庫文章下載_rev2《帥啊》網帥哥圖片下載構建代理IP池《火影忍者》漫畫下載財務報表下載小助手一小時入門網路爬蟲抖音App視訊下載_rev1抖音App視訊下載_

18awk經典實戰案例

回到: Linux系列文章 Shell系列文章 Awk系列文章 介紹 這些案例是我收集起來的,大多都是我自己遇到過的,有些比較經典,有些比較具有代表性。 這些awk案例我也錄了相關視訊的講解awk 18個經典實戰案例精講,歡迎大家去瞅瞅。 插入幾個新欄位 在"a b c d"的

Metasploit漏洞利用,三入侵主機實戰案例

connect ctrl 沖突 bsp npm ctr 利用 net wid 受害者主機 windows2003 ie模擬工具ietest ie5.5/6/7/ 漏洞:MS10_002,MS10_018,MS12-020 ----------------------

PHP經典實用案例1000

推薦特效 PHP功能外掛  更多 > 09-07  PHP合成多圖片 08-28  百度地圖根據經緯度獲取國家、州市等地址相關資訊

現學現用之windbg的高階玩法(1,3,5,13,14,76,80,81,84,118,119,121,122樓已更新,chm文件整合7篇實戰18輔助工具)

windbg用的人很少,通常被用作核心偵錯程式。 這對於windbg來說,確實大大限制了windbg的功能發揮。 因為工作的關係,樓主常常需要遠端除錯和到客戶現場排查問題。需要一款順手的偵錯程式。VC由於太大,安裝也麻煩,不能每次都給給客戶安裝一個VC,OD是一款很好的使用者態偵錯程式,但是對pdb支援的不好

【轉】18技巧實戰深度學習,資深研究員的血淚教訓

作者:chen_h 微訊號 & QQ:862251340 微信公眾號:coderpai (文/Nikolas Markou)我自 2013 年以來就一直在使用深度學習和深度置信網路。 我加入了一個綠地專案,負責選擇在計算機視覺平臺上使用的

7實戰案例、24學習視訊、12G乾貨資料...今天帶你免費入門Python資料分析!...

相信許多做資料的都有這樣的經歷:你花了大半天整合了一張資料表,卻因為其他部門的錯誤,導致表格結構

Storm容錯機制Acker詳解和實戰案例

storm acker 失敗重發 可靠性Storm中有個特殊的Executor叫acker,他們負責跟蹤spout發出的每一個Tuple的Tuple樹。當acker發現一個Tuple樹已經處理完成了,它會告訴框架回調Spout的ack(),否則回調Spout的fail()。Acker的跟蹤算法是Storm的主

程序員的18忠告

部分 方法 習慣 自己 修復 前三 構建 復雜 職業   1 想清楚,寫清楚,說清楚,才是真正的清楚!   2 多花點時間溝通清楚需求,才能把握正確方向!   3 修復需求錯誤的成本是代碼錯誤的幾十倍!   4 程序員最大的壞習慣就是:急於動手寫代碼!   5 提高開發效率

js學習總結----經典案例之選項卡

scrip ges div 視頻內容 mil line 學習總結 images ul li <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

let與expr命令的用法與實戰案例

let expr 命令 let命令的用法格式:let 賦值表達式【註】let賦值表達式功能等同於:(賦值表達式)例子:給自變量i加8[[email protected]/* */ ~]# i=2 [[email protected]/* */ ~]# let i=i+8 [

Linux服務器上監控網絡帶寬的18常用命令nload, iftop,iptraf-ng, nethogs, vnstat. nagios

器) -o -s obi 默認 系統 diag 就會 net Linux服務器上監控網絡帶寬的18個常用命令 本文介紹了一些可以用來監控網絡使用情況的Linux命令行工具。這些工具可以監控通過網絡接口傳輸的數據,並測量目前哪些數據所傳輸的速度。入站流量和出站流量分開來顯示

MySQL數據庫“十宗罪”(十大經典錯誤案例

clas 更改 表情 ins set batch 特性 iter fec Top 1: Too many connections(連接數過多,導致連接不上數據庫,業務無法正常進行) 問題還原 1 2 3 4 5 6 mysql> show vari

Java圖形界面實戰案例——實現打字母遊戲

建議 popu 會有 做的 clas 良好的 rri asc 不一定 實現打字母的遊戲 這次這個案例能夠說是頭幾次所講的內容的一個技術匯總,主要是 運用了幾大塊的知識。我們先來定義一下案例的背景:在一個300*400的窗口上。有10個隨機產生的字母下

實戰案例:構建docker容器集群 (解決方案一:使用自定義網橋連接跨主機容器)

docker一、實驗環境虛擬機a兩塊網卡 eth0 eth1 (IP地址static或者dhcp)虛擬機b兩塊網卡 eth0 eth1 (IP地址static或者dhcp)二、在兩臺虛擬機上配置網橋虛擬機a操作:apt-get install bridge-utilsvim /etc/ne

009.實戰案例::產品設計實例精解

產品設計 技術 src logs 設計 實戰案例 gif jpg alt 1.實戰案例1 2.實戰案例2 3.實戰案例3 4.實戰案例4 5.實戰案例5 6.實戰案例6 7.實戰案例7 8.實戰案例8 9.實戰案例9

一個使用Jmeter做接口性能測試的實戰案例

如果 sql查詢語句 進入 port plugins 連接 ext 目標 本地 1 安裝並配置Jmeter Jmeter的安裝不在這裏闡述,安裝步驟非常簡單。 直接進入主題 1.1 數據庫連接配置 由於測試過程需要調用數據庫獲取響應部署數據,因此需要先建立與數據庫的

Vue2.0史上最全入坑教程(下)—— 實戰案例

多少 跳轉 border src fff end har second vue 前言:經過前兩節的學習,我們已經可以創建一個vue工程了。下面我們將一起來學習制作一個簡單的實戰案例。 說明:默認我們已經用vue-cli(vue腳手架或稱前端自動化構建工具)創建好項目了 一

監控 Linux 性能的 18 命令行工具

網絡接口 網絡安全 nec 保存 perm 情況下 libc 內存分配 系統服務 It’s really very tough job for every System or Network administrator to monitor and debug Li