18個awk的經典實戰案例

来源:https://www.cnblogs.com/f-ck-need-u/archive/2019/11/27/11943913.html
-Advertisement-
Play Games

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



回到:


介紹

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

這些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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近做的一個項目中,需要用到郵箱激活功能,但是遇到一個問題! 問題描述:發送郵箱之後,郵箱的激活鏈接的href屬性不見了!!! 因為我採用的是本地的地址做測試,後來用百度的鏈接替換我的href地址又可以了。 後來百度了一下,終於在一篇文章中找到問題所在,地址在文章末尾。 原因是,在寫url時,如果訪 ...
  • 前言 我們在使用VS開發.net網站的時候,部署時可能會遇到缺少dll的問題,每次都遠程桌面登陸,然後拷貝過去,太麻煩了。我們可以使用Web Deploy這個遠程部署工具,不僅部署容易了,也方便進行迭代式的開發 服務端配置 1.iis配置,需要安裝以下功能 2.webdeploy的安裝與配置 htt ...
  • 場景 Winform控制項-DevExpress18下載安裝註冊以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100061243 安裝完DevExpress後,實現一個可以選擇多個條件的搜索功能,效果如下 實現 ...
  • 最近經常聽到embedding技術,感覺很是困惑,所以寫下此博客,對相關知識進行索引和記錄: 參考鏈接: https://www.toutiao.com/a6690680620642730510/ graph embedding 技術學習 閱讀總結: 暫無; 保持更新,資源來源自網路;更多內容請關註 ...
  • 一、搭建pptp vpn 需開放1723埠和gre協議 1.阿裡雲有個安全組需要開放埠才能訪問,需添加新的安全組規則。 登陸阿裡雲伺服器管理控制台,添加安全組規則 入/出方向都填寫 埠範圍為1723/1723 具體如圖 2.同時伺服器內部也要開放1723埠 這個在後面講 二、安裝pptp s ...
  • 本文主要為0基礎的小白準備,有一定經驗的大神請忽略。因為最近剛接觸linux,在其中也是遇到無數的彎路,本著互惠互利原則,特寫這個博客,希望後來人能少走點彎路,更快的進入狀態。話不多說,上貨。 一,首先下載安裝vmware-pro15虛擬機。(相關軟體下載地址請看結尾) 二,安裝CentOS-7-M ...
  • http://nginx.org/ NGINX官網 創建文件夾mkdir nginx進入創建的文件夾 根據自己需要下載合適版本 通過 wget http://nginx.org/download/nginx-1.17.6.tar.gz 下載文件 安裝必要插件yum -y install gcc pc ...
  • 1. 前言 本文繼續“Linux電源管理(6)_Generic PM之Suspend功能”中有關suspend同步以及PM wakeup的話題。這個話題,是近幾年Linux kernel最具爭議的話題之一,在國外Linux開發論壇,經常可以看到圍繞該話題的辯論。辯論的時間跨度和空間跨度可以持續很長, ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...