文本處理三劍客之AWK

文件處理三劍客之AWK


awk:Aho Weinberger Kernighan,報告生成器,格式化文本輸出

基本語法

  awk [options] 'program' var=value file…
  awk [options] -f programfile var=value file…
  awk [options] 'BEGIN{action;… }pattern{action;… }END {action;… }' file ...
  awk 程序可由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、 END語句塊,共3部分組成
  program 通常是被放在單引號中

選項

  -F “分隔符” 指明輸入時用到的字段分隔符
  -v var=value 變量賦值

基本格式

  awk [options] 'program' file…

Program

  pattern{action statements;..}

    pattern部分決定動作語句何時觸發及觸發事件
    BEGIN,END
    action statements對數據進行處理,放在{}內指明
    print, printf

分隔符、域和記錄

  • awk執行時,由分隔符分隔的字段(域)標記$1,$2...$n稱爲域標識。 $0爲所有域,注意:此時和shell中變量$符含義不同
  • 文件的每一行稱爲記錄
  • 省略action,則默認執行 print $0 的操作

awk的工作原理

  1. 執行BEGIN{action;… }語句塊中的語句
  2. 從文件或標準輸入(stdin)讀取一行,然後執行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。
  3. 當讀至輸入流末尾時,執行END{action;…}語句塊
  4. BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中
  5. END語句塊在awk從輸入流中讀取完所有的行之後即被執行,比如打印所有行的分析結果這類信息彙總都是在END語句塊中完成,它也是一個可選語句塊
  6. pattern語句塊中的通用命令是最重要的部分,也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊

print格式

  print item1, item2, ...

print格式要點

  逗號分隔符
  輸出item可以字符串,也可是數值;當前記錄的字段、變量或awk的表達式
  如省略item,相當於print $0

變量

  內置變量和自定義變量

FS

輸入字段分隔符,默認爲空白字符

[root@centos ~]# awk -v FS=: '{print $1,FS,$3}' /etc/passwd  
root : 0  
bin : 1  
daemon : 2  
adm : 3  
lp : 4  
sync : 5  
shutdown : 6  
halt : 7  
....
相當於
[root@centos ~]# awk -F: '{print $1,$3}' /etc/passwd  

OFS

輸出字段分隔符,默認爲空白字符

[root@centos ~]# awk -v FS=: -v OFS='---------' '{print $1,$3}' /etc/passwd
root---------0
bin---------1
daemon---------2
adm---------3
lp---------4
sync---------5
shutdown---------6
halt---------7
....

RS

輸入記錄分隔符,指定輸入時的換行符

[root@centos ~]# cat awk.txt
a,b,c;1,2,3;aa,dd,cc
zz,yy,ww;444,555,6663;AA
BB,CC
[root@centos ~]# awk -v FS="," -v RS=";" '{print $1}' awk.txt
a
1
aa
444
AA
BB

ORS

輸出記錄分隔符,輸出時用指定符號代替換行符

[root@centos ~]# awk -v FS="," -v RS=";" -v ORS='-------' '{print $1}' awk.txt
a-------1-------aa-------444-------AA
BB-------

NF

字段數量

[root@centos ~]# awk -F: '{print NF}' awk.txt #awk引用變量時,變量前不需要加$
1
1
1
[root@centos ~]# awk -F, '{print NF}' awk.txt
7
5
2
[root@centos ~]# awk -F, '{print $(NF-1)}' awk.txt
dd
555
BB

NR

記錄號

統計/etc/passwd文件裏每行對應的用戶名
[root@centos ~]# awk -F: -v OFS='----------' '{print NR,$1}' /etc/passwd
1----------root
2----------bin
3----------daemon
4----------adm
5----------lp
6----------sync
7----------shutdown
8----------halt
9----------mail
10----------operator
....
多個文件行數合併計數
[root@centos ~]# awk '{print NR}' /etc/fstab /etc/issue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

FNR:各文件分別計數,記錄號

多個文件單個計數
[root@centos ~]# awk '{print FNR}' /etc/fstab /etc/issue
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4

FILENAME:當前文件名

[root@centos ~]# awk '{print FILENAME}' /etc/fstab /etc/issue
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/issue
/etc/issue
/etc/issue
/etc/issue

ARGC:命令行參數的個數

[root@centos ~]# awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue
3

ARGV:數組,保存的是命令行所給定的各參數

[root@centos ~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue
awk
[root@centos ~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue
/etc/fstab
[root@centos ~]# awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue
/etc/issue

自定義變量(區分字符大小寫)

  1. -v var=value
  2. 在program中直接定義
[root@centos ~]# awk -F: '{title="CEO";print title":"$1}' /etc/passwd
CEO:root
CEO:bin
CEO:daemon
CEO:adm
CEO:lp
CEO:sync
CEO:shutdown
CEO:halt
....

printf命令的使用

格式化輸出

 printf “FORMAT” , item1, item2, ...

  1. 必須制定FORMAT
  2. 不會自動換行,需要顯式給出換行控制符,\n
  3. FORMAT中需要分別爲後面每個item指定格式符

格式符:與item一一對應

  %c:顯示字符的ASCII碼
  %d, %i:顯示十進制整數
  %e, %E:顯示科學計數法數值
  %f:顯示爲浮點數
  %g, %G:以科學計數法或浮點形式顯示數值
  %s:顯示字符串
  %u:無符號整數
  %%:顯示%自身

以分號爲分隔符,取第一段字符
[root@centos ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
....

修飾符

  #[.#] 第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f
  - 左對齊(默認右對齊) %-15s
  + 顯示數值的正負符號 %+d

取小數點後精度
[root@centos ~]# awk 'BEGIN{srand();printf "%.1f",rand()}'
0.5
[root@centos ~]# awk 'BEGIN{srand();printf "%.2f",rand()}'
0.05
[root@centos ~]# awk 'BEGIN{srand();printf "%.3f",rand()}'
0.799

添加註釋,並控制其顯示格式
[root@centos ~]# awk -F: 'BEGIN{print "Usernamem          UID"}{printf "%-15s %5d\n",$1,$3}' /etc/passwd | head
Usernamem          UID
root                0
bin                 1
daemon              2
adm                 3
lp                  4
sync                5
shutdown            6
halt                7
mail                8

操作符

算數操作符

  x+y, x-y, x*y, x/y, x^y, x%y
  - x:轉換爲負數
  +x:將字符串轉換爲數值

字符串操作符

  字符串連接,沒有符號的操作符

賦值操作符

  =, +=, -=, *=, /=, %=, ^=,++, --

主要觀察i++,++i的區別
[root@centos ~]# awk 'BEGIN{i=0;print i++,i}'
0 1
[root@centos ~]# awk 'BEGIN{i=0;print ++i,i}'
1 1

比較操作符

  ==, !=, >, >=, <, <=

以":"爲分隔符,匹配第三段數值爲0的行
[root@centos ~]# awk -F: '$3==0' /etc/passwd
root:x:0:0:root:/root:/bin/bash

模式匹配操作符

  ~:左邊是否和右邊匹配,包含
  !~:是否不匹配

$0代表了文件裏的全部內容,在這裏表示不匹配以"#"開頭的行
[root@centos ~]# awk '$0 !~ /^#/' /etc/fstab

UUID=66002ce1-278d-4845-b822-79b86c947af8 /                       xfs     defaults        0 0
UUID=a2c11cbb-6d9d-4a63-b961-a4d57c4c85c9 /boot                   xfs     defaults        0 0
UUID=9043785a-2496-4966-8eb6-2959d7d943ce swap                    swap    defaults        0 0
/dev/sr0 /media/cdrom iso9660 defaults 0 0

這裏表示匹配"#"開頭的行
[root@centos ~]# awk '$0 ~ /^#/' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Mar  5 20:52:08 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#

邏輯操作符

  與&&,或||,非!

這裏表示不匹配以"#"和空行的行
[root@centos ~]# awk '$0 !~ /^#/ && $0 !~ /^$/' /etc/fstab
UUID=66002ce1-278d-4845-b822-79b86c947af8 /                       xfs     defaults        0 0
UUID=a2c11cbb-6d9d-4a63-b961-a4d57c4c85c9 /boot                   xfs     defaults        0 0
UUID=9043785a-2496-4966-8eb6-2959d7d943ce swap                    swap    defaults        0 0
/dev/sr0 /media/cdrom iso9660 defaults 0 0

以":"爲分隔符,取第三段爲0或者>=1000的行
[root@centos ~]# awk -F: '$3==0 || $3>=1000' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
dxy:x:1000:1000:dxy:/home/dxy:/bin/bash

以":"爲分隔符,取第三段非大於10的行
[root@centos ~]# awk -F: '!($3>=10)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

條件表達式(三目表達式)

  selector?if-true-expression:if-false-expression

以":"作爲分隔符,當第三段數值>=1000時輸出"system user:用戶名      uid值",否則輸出"common user:用戶名      uid值"
[root@centos ~]# awk -F: '$3>=1000?user="common user":user="system user"{printf "%s: %-20s %5d\n",user,$1,$3}' passwd.txt
system user: root                     0
common user: bin                   1000
system user: daemon                   2
common user: nfsnobody            65534
system user: adm                      3
common user: lp                    1040
system user: sync                     5
system user: shutdown                 6
system user: halt                     7
common user: dxy                   1000
system user: mail                     8
system user: operator                11

awk中的PATTERN

  根據pattern條件,過濾匹配的行,再做處理

  1. 如果未指定:空模式,匹配每一行
  2. /regular expression/:僅處理能夠模式匹配到的行,需要用/ /括起來
    awk '/^UUID/{print $1}' /etc/fstab
    awk '!/^UUID/{print $1}' /etc/fstab
  3. relational expression: 關係表達式,結果爲“真”纔會被處理
    真:結果爲非0值,非空字符串
    假:結果爲空字符串或0值
  4. line ranges:行範圍
    startline,endline:/pat1/,/pat2/ 不支持直接給出數字格式
  5. BEGIN/END模式
    BEGIN{}:僅在開始處理文件中的文本之前執行一次
    END{}:僅在文本處理完成之後執行一次

再pattern中,如果未指定條件,即空模式,則匹配到每一行
[root@centos ~]# awk -F: 'i=1;j=1{print i,j}' passwd.txt
root:x:0:0:root:/root:/bin/bash
1 1
bin:x:1000:1000:bin:/bin:/sbin/nologin
1 1
daemon:x:2:2:daemon:/sbin:/sbin/nologin
1 1
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
1 1
adm:x:3:4:adm:/var/adm:/sbin/nologin
1 1
lp:x:1040:1070:lp:/var/spool/lpd:/sbin/nologin
1 1
sync:x:5:0:sync:/sbin:/bin/sync
1 1
....
匹配存在字符串"root"的行
[root@centos ~]# awk '/root/' passwd.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

匹配以字符串"root"開頭的行
[root@centos ~]# awk '/^root/' passwd.txt
root:x:0:0:root:/root:/bin/bash

匹配最後一個字段爲"/bin/bash"的行
[root@centos ~]# awk -F: '$NF=="/bin/bash"' passwd.txt
root:x:0:0:root:/root:/bin/bash
dxy:x:1000:1000:dxy:/home/dxy:/bin/bash

匹配最後一個字段以"/bash"結尾的行的第一個字段
[root@centos ~]# awk -F: '$NF ~ /bash$/{print $1}' passwd.txt
root
dxy

在關係表達式中,結果爲"真"輸出非空字符串,結果爲"假"輸出空字符串或0值
[root@centos ~]# awk '!0' passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1000:1000:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/....
[root@centos ~]# awk '!1' passwd.txt

匹配以"root"的行和以"nobady"開頭的行之間所有的內容
[root@centos ~]# awk -F: '/^root\>/,/^nobody\>/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

匹配第10行至第20行之間的行的第一個字段
[root@centos ~]# awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
10 operator
11 games
12 ftp
13 nobody
14 systemd-network
15 dbus
16 polkitd
17 libstoragemgmt
18 colord
19 rpc
20 gluster

BEGIN/END模式:BEGIN文本處理開始之前執行一次,END文本處理完成之後執行一次
[root@centos ~]# awk -F: 'BEGIN{print " USER UID \n--------------- "}{print $1,$3} END{print "=============="}' passwd.txt
 USER UID
---------------
root 0
bin 1000
daemon 2
nfsnobody 65534
adm 3
lp 1040
sync 5
shutdown 6
halt 7
dxy 1000
mail 8
operator 11
==============

awk控制語句:if-else

  語法
    if(condition){statement;…}[else statement]
    if(condition1){statement1}else if(condition2){statement2}else{statement3}
  使用場景
    對awk取得的整行或某個字段做條件判斷

判斷第三個字段是否>=1000,如果符合條件則print輸出第一,三字段的內容
[root@centos ~]# awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
nfsnobody 65534
dxy 1000

定義test變量,判斷test值,>=90輸出“very good”,90>=test>=60輸出“good”,<=60時輸出“no good”
[root@centos ~]# awk 'BEGIN{test=80;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
good
[root@centos ~]# awk 'BEGIN{test=90;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
very good
[root@centos ~]# awk 'BEGIN{test=50;if(test>=90)print "very good";else if(test>=60)print "good";else print "no good"}'
no good

awk控制語句:while循環

  語法
    while(condition){statement;…}
    條件“真”,進入循環;條件“假”,退出循環
  使用場景
    對一行內的多個字段逐一類似處理時使用
    對數組中的各元素逐一處理時使用

輸出符合條件的行
[root@centos ~]# awk '/^[[:space:]]*linux16/' /boot/grub2/grub.cfg
    linux16 /vmlinuz-3.10.0-957.el7.x86_64 root=UUID=66002ce1-278d-4845-b822-79b86c947af8 ro rhgb quiet

默認以空格作爲分隔符,輸出字段,以及字段的長度
[root@centos ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-957.el7.x86_64 30
root=UUID=66002ce1-278d-4845-b822-79b86c947af8 46
ro 2
rhgb 4
quiet 5

awk控制語句:do-while循環

  語法
    do {statement;…}while(condition)
  意義
    無論真假,至少執行一次循環體

[root@centos ~]# awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'
5050

awk控制語句:for循環

  語法
    for(expr1;expr2;expr3) {statement;…}
  特殊用法:能夠遍歷數組中的元素
    語法:for(var in array) {for-body}

默認以空格作爲分隔符,輸出字段,以及字段的長度
[root@centos ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /boot/grub2/grub.cfg
linux16 7
/vmlinuz-3.10.0-957.el7.x86_64 30
root=UUID=66002ce1-278d-4845-b822-79b86c947af8 46
ro 2
rhgb 4
quiet 5

awk控制語句:switch語句

  語法
    switch(expression) {case VALUE1 or /REGEXP/: statement1; case VALUE2 or /REGEXP2/: statement2; ...; default: statementn}

語句裏的break、continue和next

[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i} print sum}'
5050

break:符合條件直接跳出循環

[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++) {if(i%2==0)break;sum+=i}print sum}'
1

continue:符合條件跳過本次循環,繼續執行下次循環

[root@centos ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++) {if(i%2==0)continue;sum+=i}print sum}'
2500

next:符合條件則提前結束對本行處理而直接進入下一行處理

[root@centos ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
systemd-network 192
libstoragemgmt 998
rpc 32
gluster 996
....

awk數組

關聯數組:array[index-expression]

  index-expression:
    1. 可使用任意字符串;字符串要使用雙引號括起來
    2. 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,並將其值初始化爲“空串”
    3. 若要判斷數組中是否存在某元素,要使用“index in array” 格式進行遍歷

[root@centos ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
Monday

在awk中,若要遍歷數組中的每個元素,要使用for循環

  語法:
    for(var in array) {for-body}
    var會遍歷array的每個索引

[root@centos ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays){print weekdays[i]}}'
Tuesday
Monday

awk函數

函數處理

  rand():返回0和1之間一個隨機數

[root@centos ~]# awk 'BEGIN{for(i=1;i<=10;i++)print rand()}'
0.237788
0.291066
0.845814
0.152208
0.585537
0.193475
0.810623
0.173531
0.484983
0.151863

字符串處理

  length([s]):返回指定字符串的長度

[root@centos ~]# echo ${a[@]}
Mon Tur Week
[root@centos ~]# echo ${a[@]} | awk '{print length($0)}'
12
[root@centos ~]# echo ${a[@]} | awk '{print length($1)}'
3
[root@centos ~]# echo ${a[@]} | awk '{print length($2)}'
3
[root@centos ~]# echo ${a[@]} | awk '{print length($3)}'
4

  sub(r,s,[t]):對t字符串搜索r表示模式匹配的內容,並將第一個匹配內容替換爲s

[root@centos ~]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
2008-08:08 08:08:08

  gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並全部替換爲s所表示的內容

[root@centos ~]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08

  split(s,array,[r]):以r爲分隔符,切割字符串s,並將切割後的結果保存至array所表示的數組中,第一個索引值爲1,第二個索引值爲2,…

[root@centos ~]# awk 'BEGIN{time="2008:08:08 08:08:08";split(time,array,":");for(i in array){print i,array[i];}}'
4 08
5 08
1 2008
2 08
3 08 08

for…in 輸出,因爲數組是關聯數組,默認是無序的。所以通過for…in 得到是無序的數組。如果需要得到有序數組,需要通過下標獲得  

[root@centos ~]# awk 'BEGIN{time="2008:08:08 08:08:08";lens=split(time,array,":");for(i=1;i<=lens;i++){print i,array[i];}}'
1 2008
2 08
3 08 08
4 08
5 08

awk函數

自定義函數格式

  function name ( parameter, parameter, ... ) {

     statements
    return expression
   }

[root@centos ~]# chmod +x fun.awk #寫完awk程序文件要加上執行權限
[root@centos ~]# cat fun.awk
function max(x,y){
    x>y?var=x:var=y
    return var
}
BEGIN{a=3;b=6;print max(a,b)}
[root@centos ~]# awk -f fun.awk #awk -f 引用awk函數程序文件
6

向awk腳本傳遞參數

  格式:
    awkfile var=value var2=value2... Inputfile
  在BEGIN過程中不可用。直到首行輸入完成以後,變量纔可用。可以通過-v 參數,讓awk在執行BEGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數

[root@centos ~]# cat fun.awk
#!/bin/awk -f
function max(x,y){
    x>y?var=x:var=y
    return var
}
BEGIN{print max(a,b)}
[root@centos ~]# awk -v a=10 -v b=20 -f fun.awk
20
[root@centos ~]# awk -v a=100 -v b=20 -f fun.awk
100

awk中調用shell命令

system命令

  空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用""引用起來

awk調用shell命令
[root@centos ~]# awk 'BEGIN{system("hostname")}'
centos.magedu36.com
[root@centos ~]# awk 'BEGIN{system("ls")}'
a    anaconda-ks.cfg  awk.txt  Documents  fun.awk       Music       Pictures  Templates  Videos
aaa  a.sh         Desktop  Downloads  initial-setup-ks.cfg  passwd.txt  Public    test.txt

awk調用變量
[root@centos ~]# awk 'BEGIN{name="Darius";system("echo My name is " name)}'
My name is Darius
[root@centos ~]# awk 'BEGIN{score=100;system("echo Your score is  " score)}'
Your score is 100

AWK練習


解決DOS***生產案例:根據web日誌或者或者網絡連接數,監控當某個IP併發連接數或者短時內PV達到100,即調用防火牆命令封掉對應的IP,監控頻率每隔5分鐘。防火牆命令爲:iptables -A INPUT -s IP -j REJECT
vim deny_dos.sh
while true ;do
    awk '/^[0-9]/{IP[$1]++}END{for(i in IP){if (IP[i]>=100)print i}}' /var/log/httpd/access_log | while read line;do iptables -A INPUT -s $line -j
    REJECT;done
    sleep 300
done
⽂件ip_list.txt如下格式,請提取“.magedu.com"前⾯的主機名部分並寫⼊到該⽂件中

  1 blog.magedu.com
  2 www.magedu.com
  …
  999 study.magedu.com

awk -F'[" ".]' '{print $2}' ip_list.txt >> ip_list.txt
統計/etc/fstab⽂件中每個⽂件系統類型出現的次數
[root@centos ~]# awk '/^[UUID\/]/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab
swap 1
xfs 2
iso9660 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章