22. 三劍客之awk

1. AWK基礎

1.1 AWK工作原理和基本用法說明

AWK:Aho, Weinberger, Kernighan,報告生成器,格式化文本輸出,GNU/Linux發布的AWK目前由自由軟件基金會(FSF)進行開發和維護,通常也稱它為 GNU AWK

有多種版本:

  • AWK:原先來源于 AT & T 實驗室的的AWK
  • NAWK:New awk,AT & T 實驗室的AWK的升級版
  • GAWK:即GNU AWK. 所有的GNU/Linux發布版都自帶GAWK,它與AWK和NAWK完全兼容

gawk:模式掃描和處理語言,可以實現下面功能

  • 文本處理
  • 輸出格式化的文本報表
  • 執行算數運算
  • 執行字符串操作

格式:

awk [options]   'program' var=value   file…
awk [options]   -f programfile var=value file…

說明:

program通常是被放在單引號中,并可以由三種部分組成

  • BEGIN語句塊
  • 模式匹配的通用語句塊
  • END語句塊

格式:

awk 選項 PATTERN'BEGIN{BEGIN ACTION}{文本處理 ACTION}ENG{END ACTION}' 文件路徑

常見選項:

  • -F “分隔符” 指明輸入時用到的字段分隔符,默認的分隔符是若干個連續空白符
  • -v var=value 變量賦值; 即可定義內置變量, 也可定義自定義變量

Program格式:

pattern{action statements;..}

pattern:決定動作語句何時觸發及觸發事件,比如:BEGIN,END,正則表達式等

如果省略了pattern, 那么就是對所有行做處理

action statements:對數據進行處理,放在{}內指明,常見:print, printf

如果省略了action, 那么就是對所有列做處理

范例: 省略pattern和action. 如果省略了action, 那么program內的關系表達式必須返回真(非0值, 非空字符串). 否則不會對文本處理

[root@demo-c8 ~]# awk '' /etc/fstab 
[root@demo-c8 ~]# awk '0' /etc/fstab 
[root@demo-c8 ~]# awk '1' /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Mon Aug 15 16:52:19 2022
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=b1ab1ace-2582-4afd-8693-39bd9855041c /                       xfs     defaults        0 0
UUID=d5131695-82b3-4a23-bc28-5c8a4bf381a0 /boot                   ext4    defaults        1 2
UUID=bdd66510-e510-4fe7-ba71-e2a35e6dc492 /data                   xfs     defaults        0 0
UUID=05c944fb-d6f9-4544-ba10-8b7bf3cc8fed swap                    swap    defaults        0 0
[root@demo-c8 ~]# awk '"hello"' /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Mon Aug 15 16:52:19 2022
#
# 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.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=b1ab1ace-2582-4afd-8693-39bd9855041c /                       xfs     defaults        0 0
UUID=d5131695-82b3-4a23-bc28-5c8a4bf381a0 /boot                   ext4    defaults        1 2
UUID=bdd66510-e510-4fe7-ba71-e2a35e6dc492 /data                   xfs     defaults        0 0
UUID=05c944fb-d6f9-4544-ba10-8b7bf3cc8fed swap                    swap    defaults        0 0

awk工作過程:

image.png

第一步:執行BEGIN{action;… }語句塊中的語句

第二步:從文件或標準輸入(stdin)讀取一行,然后執行pattern{ action;… }語句塊,逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢

第三步:當讀至輸入流末尾時,執行END{action;…}語句塊

BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中

END語句塊在awk從輸入流中讀取完所有的行之后即被執行,比如打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊

pattern語句塊中的通用命令是最重要的部分,也是可選的. 如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊

分隔符, 域和記錄:

awk會把讀入的文件或者標準輸入, 當做一個表格格式來處理. 默認按照\n來區分兩行, 當然也可以自定義如何劃分不同的行. 比如: 自定義;為分隔符, 那么;前面的為一行, ;后面的為一行

  • 由分隔符分隔的字段(列column,域field)標記$1,$2...$n稱為域標識,$0為所有域,注意:和Shell中變量$符含義不同
$1: 第一列
$2: 第二列
...
$0: 所有列
  • 文件的每一行稱為記錄record
  • 如果省略action,則默認執行 print $0 的操作, 也就是對所有列, 做處理

常用的action分類:

  • output statements:print,printf
  • Expressions:算術,比較表達式等
  • Compound statements:組合語句
  • Control statements:if, while等
  • input statements

awk控制語句:

  • { statements;… } 組合語句
  • if(condition) {statements;…}
  • if(condition) {statements;…} else {statements;…}
  • while(conditon) {statments;…}
  • do {statements;…} while(condition)
  • for(expr1;expr2;expr3) {statements;…}
  • break
  • continue
  • exit

1.2 動作print

格式:

print item1, item2, ...

說明:

  • 逗號分隔符
  • 輸出item可以是字符串,也可是數值;當前記錄的字段、變量或awk的表達式
  • 如果省略item,相當于print $0
  • 固定字符需要用""引起來,而變量和數字不需要
abc: 變量
"abc": 純字符串

范例: print默認會對傳給awk的標準輸入做打印, 也就是打印整行, $0

root@u18:~# awk '{print}'
aa
aa
bb
bb
cc
cc

root@u18:~# cat /etc/fstab | awk '{print}'
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=f906b5aa-3e5b-4e12-8f11-55f55c41e1b0 /               ext4    errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
UUID=24239793-a342-4d7f-8773-e7381727a5dd /boot           ext4    defaults        0       2
# /data was on /dev/sda4 during installation
UUID=a328accf-9575-4343-976b-751c27cdb8ec /data           ext4    defaults        0       2
# swap was on /dev/sda5 during installation
UUID=0f94202e-4796-4835-b329-75425a807dcd none            swap    sw              0       0
root@u18:~# awk '{print}' < /etc/fstab 
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=f906b5aa-3e5b-4e12-8f11-55f55c41e1b0 /               ext4    errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
UUID=24239793-a342-4d7f-8773-e7381727a5dd /boot           ext4    defaults        0       2
# /data was on /dev/sda4 during installation
UUID=a328accf-9575-4343-976b-751c27cdb8ec /data           ext4    defaults        0       2
# swap was on /dev/sda5 during installation
UUID=0f94202e-4796-4835-b329-75425a807dcd none            swap    sw              0       0

范例: awk可以直接打印文件的全部內容

root@u18:~# awk '{print}' /etc/fstab 
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=f906b5aa-3e5b-4e12-8f11-55f55c41e1b0 /               ext4    errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
UUID=24239793-a342-4d7f-8773-e7381727a5dd /boot           ext4    defaults        0       2
# /data was on /dev/sda4 during installation
UUID=a328accf-9575-4343-976b-751c27cdb8ec /data           ext4    defaults        0       2
# swap was on /dev/sda5 during installation
UUID=0f94202e-4796-4835-b329-75425a807dcd none            swap    sw              0       0

范例: 打印固定字符串. print接固定字符串, 就是打印固定內容

root@u18:~# awk '{print "hello awk"}'
aaa
hello awk
vvv
hello awk
ccc
hello awk

# seq 10, 表示awk打印print的固定字符串10次
root@u18:~# seq 10 | awk '{print "hello awk"}'
hello awk
hello awk
hello awk
hello awk
hello awk
hello awk
hello awk
hello awk
hello awk
hello awk

范例: 域分隔符, 默認為連續的空格. 分隔時默認會把多個連續的空格, 壓縮成一個

root@u18:~# df | awk '{print $5}' 
Use%
0%
1%
3%
0%
0%
0%
9%
1%
0%
root@u18:~# df | awk '{print $5 }' | awk -F'%' '{print $1}'
Use
0
1
3
0
0
0
9
1
0

范例: 自定義域分隔符, -F選項

root@u18:~# awk -F":" '{print $1,$3}' /etc/passwd
root 0
daemon 1
bin 2
sys 3
sync 4
games 5
...

范例: 文本分隔后, 默認會用空格作為列的分隔符. 也可以指定新的分隔符

# 新的分隔符在print里, 必須用雙引號括起來
root@u18:~# awk -F':' '{print $1":"$3}' /etc/passwd
root:0
daemon:1
bin:2
sys:3
sync:4
games:5
...

范例: 指定table鍵為輸出時的分隔符

root@u18:~# awk -F: '{print $1"\t"$3}' /etc/passwd
root    0
daemon  1
bin 2
sys 3
sync    4
games   5
man 6
lp  7
mail    8
news    9
...

范例: 統計一個網站訪問量最大的前5個ip

root@u18:~# sed -nr '1,5p' access_log 
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "GET / HTTP/1.1" 200 912 "-" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "POST /webnoauth/model.cgi HTTP/1.1" 404 293 "http://172.18.0.1/webnoauth/model.cgi" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "GET /router/get_rand_key.cgi HTTP/1.1" 404 297 "http://172.18.0.1/router/get_rand_key.cgi" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "GET /router/get_rand_key.cgi HTTP/1.1" 404 297 "http://172.18.0.1/router/get_rand_key.cgi" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "GET /router/get_rand_key.cgi HTTP/1.1" 404 297 "http://172.18.0.1/router/get_rand_key.cgi" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
root@u18:~# awk '{print $1}' access_log | sort  | uniq -c | sort -k1 -nr | head -n5 
   4870 172.20.116.228
   3429 172.20.116.208
   2834 172.20.0.222
   2613 172.20.112.14
   2267 172.20.0.227

范例: 分隔文本時, 可以指定多個分隔符. 此時, 凡是被指定分隔符隔開的, 都是單獨的一列. 這樣可以避免因為分隔符不同, 需要多次對文本進行處理的情況

# [[:space:]]+|%: 擴展正則表達式, 表示一個以上包括一個空格, 或者%都作為分隔符
root@u18:~# df | awk -F"[[:space:]]+|%" '{print $5}'
Use
0
1
3
0
0
0
9
1
0

范例: 文件host_list.log 如下格式,請提取”.xxx.com”前面的主機名部分并寫回到該文件中

1 www.xxx.com
2 blog.xxx.com
3 study.xxx.com
4 linux.xxx.com
5 python.xxx.com
root@u18:/opt# awk -F"[ .]" '{print $2}' host_list.org  
www
blog
study
linux
python
root@u18:/opt# awk -F"[ .]" '{print $2}' host_list.org  >> host_list.org
root@u18:/opt# cat host_list.org
1 www.xxx.com
2 blog.xxx.com
3 study.xxx.com
4 linux.xxx.com
5 python.xxx.com
www
blog
study
linux
python

1.3 AWK變量

awk中的變量分為:內置和自定義變量

變量定義格式:

-v var=value 變量賦值; 即可定義內置變量, 也可定義自定義變量

awk變量的引用格式:

-v FS=":"
引用awk變量不用寫$, 直接寫FS即可

常見的內置變量:

  • FS(Field Separater): 輸入字段分隔符,默認為空格,功能相當于 -F. 但是-F 和 FS變量功能一樣,同時使用會沖突

范例: 指定FS為":"

root@u18:/opt# awk -v FS=":" '{print $1,$2}' /etc/passwd
root x
daemon x
bin x
sys x
sync x
games x
...

范例: 輸出分隔符變量也可引用輸入分隔符變量

root@u18:/opt# awk -v FS=":" '{print $1FS$2}' /etc/passwd
root:x
daemon:x
bin:x
sys:x
sync:x
games:x
...

范例: awk也可以引用Shell的變量

root@u18:/opt# var=":"; awk -v FS=$var '{print $1FS$2}' /etc/passwd
root:x
daemon:x
bin:x
sys:x
sync:x
games:x
...
  • OFS: 輸出字段分隔符,默認為空格

范例: 指定OFS為"===="

root@u18:/opt# awk -F":" -v  OFS="======" '{print $1,$2}' /etc/passwd
root======x
daemon======x
bin======x
sys======x
sync======x
games======x
...
root@u18:/opt# awk -v FS=":" -v  OFS="======" '{print $1, $2}' /etc/passwd
root======x
daemon======x
bin======x
sys======x
...
  • RS:輸入記錄record分隔符,指定輸入時的換行符. 默認為\n

范例: 指定";"為record分隔符

root@u18:/opt# vim f1.txt
a,b,c;11,22
33,44;xx,yy,zz
m,n;xxx
# 指定分號為record分隔符, 那么a b c是一行, 11 22 33 44是一行, xx yy zz m n是一行, xxx是一行
# 但是因為22, zz, xxx后本身就有換行符, 會繼續保留, 所以才又換一次行
root@u18:/opt# awk -v RS=";" '{print $0}' f1.txt 
a,b,c
11,22  # 文本中, 22后面有換行符, 會繼續保留
33,44
xx,yy,zz
m,n
xxx # xxx后有換行符

root@u18:/opt# 
  • NR:打印record的編號

范例: NR變量可以顯示record編號, 用于區分awk的record和Shell本身的換行

root@u18:/opt# awk -v RS=";" '{print NR,$0}' f1.txt 
1 a,b,c  # record1
2 11,22 # record 2
33,44
3 xx,yy,zz # record3
m,n
4 xxx # record4

root@u18:/opt# 
  • ORS:輸出記錄分隔符,輸出時用指定符號代替換行符. 默認會用換行符

范例: 指定"+++"為輸出時record換行符

root@u18:/opt# awk -v RS=";" -v ORS="+++" '{print NR,$0}' f1.txt 
1 a,b,c+++2 11,22
33,44+++3 xx,yy,zz
m,n+++4 xxx
+++root@u18:/opt#
  • NF:字段數量

范例: NF顯示的是, 根據輸入列分隔符分隔后, 每一行有多少個字段. 所以一共有幾行, 就會返回幾行

root@u18:/opt# awk -F":" '{print NF}' /etc/passwd
root@u18:/opt# awk -F":" '{print NF}' /etc/passwd
7
7
7
7
7
7
7
7
7
7
7
7
7
...

$NF: 代表最后一個字段

root@u18:/opt# awk -F":" '{print $NF}' /etc/passwd
/bin/bash
/usr/sbin/nologin
/usr/sbin/nologin
/usr/sbin/nologin
...

$(NF-1): 代表倒數第二個字段

root@u18:/opt# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
...
root@u18:/opt# awk -F":" '{print $(NF-1)}' /etc/passwd
/root
/usr/sbin
/bin
/dev
/bin
/usr/games
/var/cache/man
/var/spool/lpd
/var/mail
/var/spool/news
/var/spool/uucp
/bin
...

范例: 取源碼包的版本信息

root@u18:/opt# tar cvf app.v1.tar.gz /etc
root@u18:/opt# tar cvf app.v2.tar.gz /etc
root@u18:/opt# tar cvf app.v3.tar.gz /etc
root@u18:/opt# tar cvf app.v4.tar.gz /etc
root@u18:/opt# tar cvf app.v5.tar.gz /etc
root@u18:/opt# ll app*
-rw-r--r-- 1 root root 3225600 Sep 17 22:06 app.v1.tar.gz
-rw-r--r-- 1 root root 3225600 Sep 17 22:09 app.v2.tar.gz
-rw-r--r-- 1 root root 3225600 Sep 17 22:09 app.v3.tar.gz
-rw-r--r-- 1 root root 3225600 Sep 17 22:09 app.v4.tar.gz
-rw-r--r-- 1 root root 3225600 Sep 17 22:09 app.v5.tar.gz
# 以"."為輸入分隔符, 取倒數第三個字段, 即為版本號

root@u18:/opt# ls app.* | xargs -n1 |  awk -F"." '{print $(NF-2)}'
v1
v2
v3
v4
v5
# 這里其實不用xargs進行轉置, 因為ls的結果雖然是以橫行顯示, 但本身是豎著的

root@u18:/opt# ls app.* |  awk -F"." '{print $(NF-2)}'
v1
v2
v3
v4
v5
  • FNR:各文件分別計數記錄的編號. 默認情況下, 多個文件會統一編號

范例: 利用FNR分別統計各文件記錄的編號

root@u18:/opt# awk -F":" '{print FNR,$1}' /etc/passwd /etc/group
1 root
2 daemon
3 bin
4 sys
5 sync
6 games
7 man
8 lp
9 mail
10 news
11 uucp
12 proxy
13 www-data
14 backup
15 list
16 irc
17 gnats
18 nobody
19 systemd-network
20 systemd-resolve
21 syslog
22 messagebus
23 _apt
24 lxd
25 uuidd
26 dnsmasq
27 landscape
28 sshd
29 pollinate
30 david
1 root
2 daemon
3 bin
4 sys
5 adm
6 tty
7 disk
8 lp
9 mail
10 news
11 uucp
12 man
13 proxy
14 kmem
15 dialout
16 fax
17 voice
18 cdrom
19 floppy
20 tape
21 sudo
22 audio
23 dip
24 www-data
25 backup
26 operator
27 list
28 irc
29 src
30 gnats
31 shadow
32 utmp
33 video
34 sasl
35 plugdev
36 staff
37 games
38 users
39 nogroup
40 systemd-journal
41 systemd-network
42 systemd-resolve
43 input
44 crontab
45 syslog
46 messagebus
47 lxd
48 mlocate
49 uuidd
50 ssh
51 landscape
52 david
53 lpadmin
54 sambashare
  • FILENAME:返回當前文件名, 配合FNR使用, 返回的record編號會標記屬于哪個文件
root@u18:/opt# awk -F":" '{print FNR,$1,FILENAME}' /etc/passwd /etc/group
1 root /etc/passwd
2 daemon /etc/passwd
3 bin /etc/passwd
4 sys /etc/passwd
5 sync /etc/passwd
6 games /etc/passwd
7 man /etc/passwd
8 lp /etc/passwd
9 mail /etc/passwd
10 news /etc/passwd
11 uucp /etc/passwd
12 proxy /etc/passwd
13 www-data /etc/passwd
14 backup /etc/passwd
15 list /etc/passwd
16 irc /etc/passwd
17 gnats /etc/passwd
18 nobody /etc/passwd
19 systemd-network /etc/passwd
20 systemd-resolve /etc/passwd
21 syslog /etc/passwd
22 messagebus /etc/passwd
23 _apt /etc/passwd
24 lxd /etc/passwd
25 uuidd /etc/passwd
26 dnsmasq /etc/passwd
27 landscape /etc/passwd
28 sshd /etc/passwd
29 pollinate /etc/passwd
30 david /etc/passwd
1 root /etc/group
2 daemon /etc/group
3 bin /etc/group
4 sys /etc/group
5 adm /etc/group
6 tty /etc/group
7 disk /etc/group
8 lp /etc/group
9 mail /etc/group
10 news /etc/group
11 uucp /etc/group
12 man /etc/group
13 proxy /etc/group
14 kmem /etc/group
15 dialout /etc/group
16 fax /etc/group
17 voice /etc/group
18 cdrom /etc/group
19 floppy /etc/group
20 tape /etc/group
21 sudo /etc/group
22 audio /etc/group
23 dip /etc/group
24 www-data /etc/group
25 backup /etc/group
26 operator /etc/group
27 list /etc/group
28 irc /etc/group
29 src /etc/group
30 gnats /etc/group
31 shadow /etc/group
32 utmp /etc/group
33 video /etc/group
34 sasl /etc/group
35 plugdev /etc/group
36 staff /etc/group
37 games /etc/group
38 users /etc/group
39 nogroup /etc/group
40 systemd-journal /etc/group
41 systemd-network /etc/group
42 systemd-resolve /etc/group
43 input /etc/group
44 crontab /etc/group
45 syslog /etc/group
46 messagebus /etc/group
47 lxd /etc/group
48 mlocate /etc/group
49 uuidd /etc/group
50 ssh /etc/group
51 landscape /etc/group
52 david /etc/group
53 lpadmin /etc/group
54 sambashare /etc/group
  • ARGC:返回awk命令行參數的個數

范例: ARGV返回awk命令參數個數, '為第一個', /etc/passwd為第二個, /etc/group為第三個

root@u18:/opt# awk -F":" '{print ARGC,FNR,$1,FILENAME}' /etc/passwd /etc/group
3 1 root /etc/passwd
3 2 daemon /etc/passwd
3 3 bin /etc/passwd
3 4 sys /etc/passwd
3 5 sync /etc/passwd
3 6 games /etc/passwd
3 7 man /etc/passwd
3 8 lp /etc/passwd
3 9 mail /etc/passwd
3 10 news /etc/passwd
3 11 uucp /etc/passwd
3 12 proxy /etc/passwd
3 13 www-data /etc/passwd
3 14 backup /etc/passwd
3 15 list /etc/passwd
3 16 irc /etc/passwd
3 17 gnats /etc/passwd
3 18 nobody /etc/passwd
3 19 systemd-network /etc/passwd
3 20 systemd-resolve /etc/passwd
3 21 syslog /etc/passwd
3 22 messagebus /etc/passwd
3 23 _apt /etc/passwd
3 24 lxd /etc/passwd
3 25 uuidd /etc/passwd
3 26 dnsmasq /etc/passwd
3 27 landscape /etc/passwd
3 28 sshd /etc/passwd
3 29 pollinate /etc/passwd
3 30 david /etc/passwd
3 1 root /etc/group
3 2 daemon /etc/group
3 3 bin /etc/group
3 4 sys /etc/group
3 5 adm /etc/group
3 6 tty /etc/group
3 7 disk /etc/group
3 8 lp /etc/group
3 9 mail /etc/group
3 10 news /etc/group
3 11 uucp /etc/group
3 12 man /etc/group
3 13 proxy /etc/group
3 14 kmem /etc/group
3 15 dialout /etc/group
3 16 fax /etc/group
3 17 voice /etc/group
3 18 cdrom /etc/group
3 19 floppy /etc/group
3 20 tape /etc/group
3 21 sudo /etc/group
3 22 audio /etc/group
3 23 dip /etc/group
3 24 www-data /etc/group
3 25 backup /etc/group
3 26 operator /etc/group
3 27 list /etc/group
3 28 irc /etc/group
3 29 src /etc/group
3 30 gnats /etc/group
3 31 shadow /etc/group
3 32 utmp /etc/group
3 33 video /etc/group
3 34 sasl /etc/group
3 35 plugdev /etc/group
3 36 staff /etc/group
3 37 games /etc/group
3 38 users /etc/group
3 39 nogroup /etc/group
3 40 systemd-journal /etc/group
3 41 systemd-network /etc/group
3 42 systemd-resolve /etc/group
3 43 input /etc/group
3 44 crontab /etc/group
3 45 syslog /etc/group
3 46 messagebus /etc/group
3 47 lxd /etc/group
3 48 mlocate /etc/group
3 49 uuidd /etc/group
3 50 ssh /etc/group
3 51 landscape /etc/group
3 52 david /etc/group
3 53 lpadmin /etc/group
3 54 sambashare /etc/group
  • ARGV:數組,保存的是命令行所給定的各參數,返回某一個參數用:ARGV[0],....... ARGV[0]返回awk命令本身, 超出參數個數, 返回空白

范例: ARGV返回第n個參數

root@u18:/opt# awk -F":" '{print ARGV[0]}' /etc/passwd /etc/group
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
awk
root@u18:/opt# awk -F":" '{print ARGV[1]}' /etc/passwd /etc/group
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
/etc/passwd
root@u18:/opt# awk -F":" '{print ARGV[2]}' /etc/passwd /etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group
/etc/group

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

-v var=value 
在program中直接定義

范例: 在處理文件之前, 先打印一次變量, 用于制作表頭等情況. BEGIN{這里的內容, 會在處理文本之前先執行一次}

root@u18:/opt# awk 'BEGIN{test="hello,world"; print test}'
hello,world
root@u18:/opt# awk -v test="hello,awk" 'BEGIN{print test}'
hello,awk
root@u18:/opt# awk -v test="hello,awk" 'BEGIN{print test; test="hello,world";print test}'
hello,awk
hello,world

范例: 在awk的program中, 可以使用鏈式賦值, 但是在awk外部不支持

root@u18:/opt# awk  'BEGIN{test1=test2="hello,world"; print test1; print test2; print "hello,awk"}'
hello,world
hello,world
hello,awk

范例: awk打印多個字符串, 可以只寫一個print命令

root@u18:/opt# awk  'BEGIN{test1=test2="hello,world"; print test1,test2,"hello,awk"}'
hello,world hello,world hello,awk

范例: awk的變量不支持先引用, 后賦值

root@u18:/opt# awk -F":" '{sex="male";print $1,sex,age;age=18}' /etc/passwd
root male # 第一行記錄的age為空, 說明處理第一行時, 運行到print age發現age沒賦值, 所以返回空
daemon male 18 # 第二行開始有age的值, 因為第一行處理完, age=18就執行了, 所以第二行開始都是有age值的
bin male 18
sys male 18
sync male 18
games male 18
man male 18
lp male 18
mail male 18
news male 18
uucp male 18
proxy male 18
www-data male 18
backup male 18
list male 18
irc male 18
gnats male 18
nobody male 18
systemd-network male 18
systemd-resolve male 18
syslog male 18
messagebus male 18
_apt male 18
lxd male 18
uuidd male 18
dnsmasq male 18
landscape male 18
sshd male 18
pollinate male 18
david male 18

范例: 可以把awk的program部分寫到文件里, 之后在命令中通過-f選項調用

root@u18:/opt# vim awk.txt
{print $(NF-1)}        
root@u18:/opt# awk -F":" -f awk.txt /etc/passwd
/root
/usr/sbin
/bin
/dev
/bin
/usr/games
/var/cache/man
/var/spool/lpd
/var/mail
/var/spool/news
/var/spool/uucp
/bin
/var/www
/var/backups
/var/list
/var/run/ircd
/var/lib/gnats
/nonexistent
/run/systemd/netif
/run/systemd/resolve
/home/syslog
/nonexistent
/nonexistent
/var/lib/lxd/
/run/uuidd
/var/lib/misc
/var/lib/landscape
/run/sshd
/var/cache/pollinate
/home/david

1.4 動作printf

printf可以實現格式化輸出

格式:

# 在'program中書寫'
printf "FORMAT", item1, item2,...

說明:

  • 必須指定FORMAT
  • 不會自動換行, 需要顯示給出換行控制符\n
  • FORMAT中需要分別為后面每個item指定格式符

格式符: 與item一一對應

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

修飾符:

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

范例:

awk -F:   '{printf "%s",$1}' /etc/passwd
awk -F:   '{printf "%s\n",$1}' /etc/passwd
awk -F:   '{printf "%20s\n",$1}' /etc/passwd
awk -F:   '{printf "%-20s\n",$1}' /etc/passwd
awk -F:   '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F:   '{printf "Username: %s\n",$1}' /etc/passwd
awk -F:   '{printf “Username: %sUID:%d\n",$1,$3}' /etc/passwd
awk -F:   '{printf "Username: %25sUID:%d\n",$1,$3}' /etc/passwd
awk -F:   '{printf "Username: %-25sUID:%d\n",$1,$3}' /etc/passwd
  • %s指代的就是$1的內容
[19:20:08 root@centos7 ~]#awk -F: '{printf "%s", $1}' /etc/passwd
rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdsshdpostfixtcpdump[19:20:38 root@centos7 ~]#
  • 換行符需要顯示指定\n
[19:20:03 root@centos7 ~]#awk -F: '{printf "%s\n", $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
sshd
postfix
tcpdump
[19:21:16 root@centos7 ~]#awk -F":" '{printf "%20s\n",$1}' /etc/passwd
                root
                 bin
              daemon
                 adm
                  lp
                sync
            shutdown
                halt
                mail
            operator
               games
                 ftp
              nobody
     systemd-network
                dbus
             polkitd
                sshd
             postfix
             tcpdump
[19:22:15 root@centos7 ~]#awk -F":" '{printf "%-20s\n",$1}' /etc/passwd
root                
bin                 
daemon              
adm                 
lp                  
sync                
shutdown            
halt                
mail                
operator            
games               
ftp                 
nobody              
systemd-network     
dbus                
polkitd             
sshd                
postfix             
tcpdump             
[19:22:58 root@centos7 ~]#awk -F":" '{printf "Username: %s\n",$1}' /etc/passwd
Username: root
Username: bin
Username: daemon
Username: adm
Username: lp
Username: sync
Username: shutdown
Username: halt
Username: mail
Username: operator
Username: games
Username: ftp
Username: nobody
Username: systemd-network
Username: dbus
Username: polkitd
Username: sshd
Username: postfix
Username: tcpdump
  • 打印多列, 需要分別指定格式, 并且指定列的輸出分隔符, 否則兩列會連在一起
[19:25:32 root@centos7 ~]#awk -F":" '{printf "Username: %s | UID: %d\n", $1, $3}' /etc/passwd
Username: root | UID: 0
Username: bin | UID: 1
Username: daemon | UID: 2
Username: adm | UID: 3
Username: lp | UID: 4
Username: sync | UID: 5
Username: shutdown | UID: 6
Username: halt | UID: 7
Username: mail | UID: 8
Username: operator | UID: 11
Username: games | UID: 12
Username: ftp | UID: 14
Username: nobody | UID: 99
Username: systemd-network | UID: 192
Username: dbus | UID: 81
Username: polkitd | UID: 999
Username: sshd | UID: 74
Username: postfix | UID: 89
Username: tcpdump | UID: 72
[19:26:34 root@centos7 ~]#awk -F":" '{printf "Username: %-25s UID: %d\n", $1, $3}' /etc/passwd
Username: root                      UID: 0
Username: bin                       UID: 1
Username: daemon                    UID: 2
Username: adm                       UID: 3
Username: lp                        UID: 4
Username: sync                      UID: 5
Username: shutdown                  UID: 6
Username: halt                      UID: 7
Username: mail                      UID: 8
Username: operator                  UID: 11
Username: games                     UID: 12
Username: ftp                       UID: 14
Username: nobody                    UID: 99
Username: systemd-network           UID: 192
Username: dbus                      UID: 81
Username: polkitd                   UID: 999
Username: sshd                      UID: 74
Username: postfix                   UID: 89
Username: tcpdump                   UID: 72
[root@demo-c8 ~]# awk -F":"  '{printf "%-20s %s\n", $1,$3 }' /etc/passwd
root                 0
bin                  1
daemon               2
adm                  3
lp                   4
sync                 5
shutdown             6
halt                 7
mail                 8
operator             11
games                12
ftp                  14
nobody               65534
dbus                 81
systemd-coredump     999
systemd-resolve      193
tss                  59
polkitd              998
geoclue              997
rtkit                172
pulse                171
libstoragemgmt       996
qemu                 107
usbmuxd              113
unbound              995
rpc                  32
gluster              994
chrony               993
setroubleshoot       992
pipewire             991
saslauth             990
dnsmasq              984
radvd                75
clevis               983
cockpit-ws           982
cockpit-wsinstance   981
sssd                 980
flatpak              979
colord               978
gdm                  42
rpcuser              29
gnome-initial-setup  977
sshd                 74
avahi                70
rngd                 976
tcpdump              72
wang                 1000
  • 打印title, 湊出表格形式
[root@demo-c8 ~]# awk -F":"  'BEGIN{print "|---------------------------|\n|       Usename&UID         |\n-----------------------------"}{printf "|%-20s|%-6s|\n-----------------------------\n", $1,$3 }' /etc/passwd 
|---------------------------|
|       Usename&UID         |
-----------------------------
|root                |0     |
-----------------------------
|bin                 |1     |
-----------------------------
|daemon              |2     |
-----------------------------
|adm                 |3     |
-----------------------------
|lp                  |4     |
-----------------------------
|sync                |5     |
-----------------------------
|shutdown            |6     |
-----------------------------
|halt                |7     |
-----------------------------
|mail                |8     |
-----------------------------
|operator            |11    |
-----------------------------
|games               |12    |
-----------------------------
|ftp                 |14    |
-----------------------------
|nobody              |65534 |
-----------------------------
|dbus                |81    |
-----------------------------
|systemd-coredump    |999   |
-----------------------------
|systemd-resolve     |193   |
-----------------------------
|tss                 |59    |
-----------------------------
|polkitd             |998   |
-----------------------------
|geoclue             |997   |
-----------------------------
|rtkit               |172   |
-----------------------------
|pulse               |171   |
-----------------------------
|libstoragemgmt      |996   |
-----------------------------
|qemu                |107   |
-----------------------------
|usbmuxd             |113   |
-----------------------------
|unbound             |995   |
-----------------------------
|rpc                 |32    |
-----------------------------
|gluster             |994   |
-----------------------------
|chrony              |993   |
-----------------------------
|setroubleshoot      |992   |
-----------------------------
|pipewire            |991   |
-----------------------------
|saslauth            |990   |
-----------------------------
|dnsmasq             |984   |
-----------------------------
|radvd               |75    |
-----------------------------
|clevis              |983   |
-----------------------------
|cockpit-ws          |982   |
-----------------------------
|cockpit-wsinstance  |981   |
-----------------------------
|sssd                |980   |
-----------------------------
|flatpak             |979   |
-----------------------------
|colord              |978   |
-----------------------------
|gdm                 |42    |
-----------------------------
|rpcuser             |29    |
-----------------------------
|gnome-initial-setup |977   |
-----------------------------
|sshd                |74    |
-----------------------------
|avahi               |70    |
-----------------------------
|rngd                |976   |
-----------------------------
|tcpdump             |72    |
-----------------------------
|wang                |1000  |
-----------------------------

1.5 操作符

算數運算符:

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

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

賦值操作符:

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

范例: 自增

[19:29:30 root@centos7 ~]#awk 'BEGIN{i=0;print i++,i}' # 先打印i, 再自增, 然后重新打印
0 1
[19:29:49 root@centos7 ~]#awk 'BEGIN{i=0;print ++i,i}' # 先自增打印i, 然后再打印一遍i
1 1

比較操作符:

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

范例: 打印/etc/issue文件的第二行record

[19:36:17 root@centos7 ~]#awk 'NR==2' /etc/issue
Kernel \r on an \m

范例: 打印UID>=1000的record

[19:36:26 root@centos7 ~]#awk '$3>=1000' /etc/passwd
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin

范例: 取奇數, 偶數行

[19:38:39 root@centos7 ~]#seq 10 | awk 'NR%2==0'
2
4
6
8
10
[19:39:16 root@centos7 ~]#seq 10 | awk 'NR%2==1'
1
3
5
7
9
[19:39:19 root@centos7 ~]#seq 10 | awk 'NR%2!=0'
1
3
5
7
9

范例: 取ip地址

[19:45:44 root@centos7 ~]#ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.192.7  netmask 255.255.255.0  broadcast 192.168.192.255
        inet6 fe80::20c:29ff:fe0d:c854  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:0d:c8:54  txqueuelen 1000  (Ethernet)
        RX packets 3731  bytes 324962 (317.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1901  bytes 235371 (229.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[19:45:29 root@centos7 ~]#ifconfig eth0 | awk 'NR==2{print $2}'
192.168.192.7

模式匹配符:

~ 左邊是否和右邊匹配,包含關系. 配合正則表達式, 判斷左邊內容, 是否包含右邊內容
!~ 是否不匹配, 左邊內容, 是否不包含右邊內容

格式:

awk 選項 '$指定列范圍 ~ /指定的列范圍是否包含該字符串/{ACTION}' 文件路徑

范例:

[root@demo-c8 opt]# awk -F":" '$0 ~ /root/{print $1}' /etc/passwd
root
operator

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

selector?if-true-expression:if-false-expression
  • select: 模式匹配
  • if-true-expression: 行匹配成功, 則執行該命令
  • if-false-expression: 行匹配不成功, 則執行該命令

范例: 計算每一行第三列的值是否大于等于1000, 如果是, 則給usertype賦值為"Common User", 如果不是, 賦值為"SysUser". 最后打印$1的內容, 以及usertype變量的值

[root@demo-c8 opt]# awk -F: '{$3>=1000?usertype="Common User":usertype="SysUser";printf "%-20s:%12s\n",$1,usertype}'  /etc/passwd
root                :     SysUser
bin                 :     SysUser
daemon              :     SysUser
adm                 :     SysUser
lp                  :     SysUser
sync                :     SysUser
shutdown            :     SysUser
halt                :     SysUser
mail                :     SysUser
operator            :     SysUser
games               :     SysUser
ftp                 :     SysUser
nobody              : Common User
dbus                :     SysUser
systemd-coredump    :     SysUser
systemd-resolve     :     SysUser
tss                 :     SysUser
polkitd             :     SysUser
geoclue             :     SysUser
rtkit               :     SysUser
pulse               :     SysUser
libstoragemgmt      :     SysUser
qemu                :     SysUser
usbmuxd             :     SysUser
unbound             :     SysUser
rpc                 :     SysUser
gluster             :     SysUser
chrony              :     SysUser
setroubleshoot      :     SysUser
pipewire            :     SysUser
saslauth            :     SysUser
dnsmasq             :     SysUser
radvd               :     SysUser
clevis              :     SysUser
cockpit-ws          :     SysUser
cockpit-wsinstance  :     SysUser
sssd                :     SysUser
flatpak             :     SysUser
colord              :     SysUser
gdm                 :     SysUser
rpcuser             :     SysUser
gnome-initial-setup :     SysUser
sshd                :     SysUser
avahi               :     SysUser
rngd                :     SysUser
tcpdump             :     SysUser
wang                : Common User

1.6 模式PATTERN

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

  1. 如果未指定:空模式,匹配每一行

范例:

[root@demo-c8 ~]# awk -F":" '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
...
  1. /regular expression/:僅處理能被模式匹配到的行,需要用/ /括起來
  • 如果省略了action, 那么默認會執行print $0
[root@demo-c8 ~]# awk '/^UUID/' /etc/fstab
UUID=b1ab1ace-2582-4afd-8693-39bd9855041c /                       xfs     defaults        0 0
UUID=d5131695-82b3-4a23-bc28-5c8a4bf381a0 /boot                   ext4    defaults        1 2
UUID=bdd66510-e510-4fe7-ba71-e2a35e6dc492 /data                   xfs     defaults        0 0
UUID=05c944fb-d6f9-4544-ba10-8b7bf3cc8fed swap                    swap    defaults        0 0

范例: 取分區利用率數字

[root@demo-c8 ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs         3957244       0   3957244   0% /dev
tmpfs            3985412       0   3985412   0% /dev/shm
tmpfs            3985412    9832   3975580   1% /run
tmpfs            3985412       0   3985412   0% /sys/fs/cgroup
/dev/sda2       41922560 4561428  37361132  11% /
/dev/sda5       41922560  325332  41597228   1% /data
/dev/sda1         999320  192552    737956  21% /boot
tmpfs             797080    1168    795912   1% /run/user/42
tmpfs             797080       4    797076   1% /run/user/0
[root@demo-c8 ~]# df | awk -F"[[:space:]]+|%" '/^\/dev\/sd/{print $5}'
11
1
21
[root@demo-c8 ~]# df | awk -F"[[:space:]]+|%" '/^\/dev\/sd/{print $5}' | sort |  df | awk -F"[[:space:]]+|%" '/^\/dev\/sd/{print $5}' | sort | tail -n1
21
  1. relational expression: 關系表達式,結果為“真”才會被處理

真:結果為非0值,非空字符串
假:結果為空字符串或0值

范例: !0表示真, !1表示假. 使用數字時, 不用加雙引號""

[root@demo-c8 ~]# awk '!0' /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:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
polkitd:x:998:996:User for polkitd:/:/sbin/nologin
geoclue:x:997:995:User for geoclue:/var/lib/geoclue:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
libstoragemgmt:x:996:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
unbound:x:995:990:Unbound DNS resolver:/etc/unbound:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
gluster:x:994:989:GlusterFS daemons:/run/gluster:/sbin/nologin
chrony:x:993:988::/var/lib/chrony:/sbin/nologin
setroubleshoot:x:992:986::/var/lib/setroubleshoot:/sbin/nologin
pipewire:x:991:985:PipeWire System Daemon:/var/run/pipewire:/sbin/nologin
saslauth:x:990:76:Saslauthd user:/run/saslauthd:/sbin/nologin
dnsmasq:x:984:984:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
clevis:x:983:982:Clevis Decryption Framework unprivileged user:/var/cache/clevis:/sbin/nologin
cockpit-ws:x:982:980:User for cockpit web service:/nonexisting:/sbin/nologin
cockpit-wsinstance:x:981:979:User for cockpit-ws instances:/nonexisting:/sbin/nologin
sssd:x:980:978:User for sssd:/:/sbin/nologin
flatpak:x:979:977:User for flatpak system helper:/:/sbin/nologin
colord:x:978:976:User for colord:/var/lib/colord:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:977:975::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
rngd:x:976:974:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
wang:x:1000:1000:wang:/home/wang:/bin/bash
[root@demo-c8 ~]# awk '!1' /etc/passwd

范例: !n++表達式

  1. awk先判斷n的值, n=0, !n=1, 為真, 所以會處理第一行
  2. 處理完第一行, 計算n++, n=2, !n=0, 為假, 則不處理第二行
  3. 第二行雖然不處理, 但是因為是循環處理每一行, 所以之后還要判斷n, n=2, n++=3, !n=0, 為假, 所以不處理第三行, 后續所有行因為n都是為0, !n則為假, 也就都不處理了
[root@demo-c8 ~]# awk -v n=0 '!n++' /etc/passwd
root:x:0:0:root:/root:/bin/bash

范例: !++n表達式

  1. n=0, 先計算++n, n=1, !n=0, 為假, 則不處理文本
[root@demo-c8 opt]# awk -v n=0 '!++n' /etc/passwd 
[root@demo-c8 opt]# 

總結: 當pattern使用關系表達式時, 處理文本就相當于循環處理每一行, 每次處理一行內容之前, 要先判斷表達式的返回值, 返回真, 則處理, 返回假, 則不處理. 處理完一行, 接著再次判斷表達式的返回值, 然后再處理或不處理

范例: i=!i, 打印奇數行

  1. i起初沒有賦值, 為假, 那么!i就為真, 所以會處理第一行, 此時i=真
  2. 之后, 因為i為真, 那么!i就為假, 所以不會處理第二行, 此時i=假
  3. 接著再判斷表達式, 此時i=假, 那么!i則為真, 處理第三行, 也就是只處理奇數行
[root@demo-c8 opt]# seq 10 | awk 'i=!i' 
1
3
5
7
9

范例: 打印偶數行

先將i初始化為1, 真, 那么!i就是假, 和上面相反, 結果就是只處理偶數行

[root@demo-c8 opt]# seq 10 | awk -v i=1 'i=!i' 
2
4
6
8
10
[root@demo-c8 opt]# seq 10 | awk '!(i=!i)' 
2
4
6
8
10
  1. line ranges:行范圍

不支持直接用行號,但可以使用變量NR間接指定行號

范例:

[root@demo-c8 opt]# seq 10 | awk 'NR>=3 && NR<=6'
3
4
5
6

/pat1/,/pat2/ 不支持直接給出數字格式, 但支持字符匹配

范例:

[root@demo-c8 opt]# awk '/^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:65534:65534:Kernel Overflow User:/:/sbin/nologin

2. AWK條件判斷和循環控制

2.1 條件判斷if-else

語法:

if(condition)statement
if(condition){statement;…}[{else statement}
if(condition1){statement1}else if(condition2){statement2}else if(condition3){statement3}......else{statementN}

使用場景: 對awk取得的整行或某個字段做條件判斷

范例: '{if(condition)statement}'

[root@demo-c8 opt]# awk -F":" '{if($NF=="/bin/bash")print $1}' /etc/passwd
root
wang
[root@demo-c8 opt]# awk -F":" '{if($NF>5)print $0}' /etc/fstab 
UUID=b1ab1ace-2582-4afd-8693-39bd9855041c /                       xfs     defaults        0 0
UUID=d5131695-82b3-4a23-bc28-5c8a4bf381a0 /boot                   ext4    defaults        1 2
UUID=bdd66510-e510-4fe7-ba71-e2a35e6dc492 /data                   xfs     defaults        0 0
UUID=05c944fb-d6f9-4544-ba10-8b7bf3cc8fed swap                    swap    defaults        0 0
[root@demo-c8 opt]# awk -F":" '{if($3>=1000)print $1,$3}' /etc/passwd
nobody 65534
wang 1000

范例: '{if(condition1){statement1}else{statement2}}'

[root@demo-c8 opt]# awk -F":" '{if($3>=1000){printf "%-20s %s\n", $1,$3}else{printf "%-20s %s\n", $1, "common user"}}' /etc/passwd
root                 common user
bin                  common user
daemon               common user
adm                  common user
lp                   common user
sync                 common user
shutdown             common user
halt                 common user
mail                 common user
operator             common user
games                common user
ftp                  common user
nobody               65534
dbus                 common user
systemd-coredump     common user
systemd-resolve      common user
tss                  common user
polkitd              common user
geoclue              common user
rtkit                common user
pulse                common user
libstoragemgmt       common user
qemu                 common user
usbmuxd              common user
unbound              common user
rpc                  common user
gluster              common user
chrony               common user
setroubleshoot       common user
pipewire             common user
saslauth             common user
dnsmasq              common user
radvd                common user
clevis               common user
cockpit-ws           common user
cockpit-wsinstance   common user
sssd                 common user
flatpak              common user
colord               common user
gdm                  common user
rpcuser              common user
gnome-initial-setup  common user
sshd                 common user
avahi                common user
rngd                 common user
tcpdump              common user
wang                 1000

范例: awk取分區利用率大于10%的分區

[root@demo-c8 opt]# df 
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs         3957244       0   3957244   0% /dev
tmpfs            3985412       0   3985412   0% /dev/shm
tmpfs            3985412    9832   3975580   1% /run
tmpfs            3985412       0   3985412   0% /sys/fs/cgroup
/dev/sda2       41922560 4561796  37360764  11% /
/dev/sda5       41922560  325332  41597228   1% /data
/dev/sda1         999320  192552    737956  21% /boot
tmpfs             797080    1168    795912   1% /run/user/42
tmpfs             797080       4    797076   1% /run/user/0
[root@demo-c8 opt]# df | awk -F"[[:space:]]+|%" '/^\/dev\/sd/{if($5>10)print $1, $5}'
/dev/sda2 11
/dev/sda1 21
[ %]+ : 表示>=1個空格, 或者>=1個百分號
[[:space:]]+|% : 表示>=1個空格, 或者一個百分號
" +|%" : 表示>=1個空格, 或者>=1個百分號

2.2 switch語句

類似Shell中的case表達式

語法:

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

2.3 while循環

條件“真”,進入循環;條件“假”,退出循環
使用場景:

對一行內的多個字段逐一類似處理時使用
對數組中的各元素逐一處理時使用

語法:

while (condition) {statement;…}

范例: length()內置函數, 返回字符個數

[root@demo-c8 opt]# awk  'BEGIN{print length("您好世界")}' 
4
[root@demo-c8 opt]# awk  'BEGIN{print length("hello world")}' 
11

范例: awk逐列處理

[20:08:29 root@centos-7-6 ~]#awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i); i++}}' /etc/grub2.cfg
linux16 7
/vmlinuz-3.10.0-1127.el7.x86_64 31
root=UUID=ffd4773d-a205-4937-bdff-4f80e73b6ad0 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13
linux16 7
/vmlinuz-0-rescue-e5ad2c92a25b4c87b7cca719c77091ff 50
root=UUID=ffd4773d-a205-4937-bdff-4f80e73b6ad0 46
ro 2
crashkernel=auto 16
rhgb 4
quiet 5
net.ifnames=0 13
[20:08:37 root@centos-7-6 ~]#awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg
/vmlinuz-3.10.0-1127.el7.x86_64 31
root=UUID=ffd4773d-a205-4937-bdff-4f80e73b6ad0 46
crashkernel=auto 16
net.ifnames=0 13
/vmlinuz-0-rescue-e5ad2c92a25b4c87b7cca719c77091ff 50
root=UUID=ffd4773d-a205-4937-bdff-4f80e73b6ad0 46
crashkernel=auto 16
net.ifnames=0 13

范例: 打印1,2,..100

[root@demo-c8 opt]# awk -v i=1 'BEGIN{while(i<=100){print i;i++}}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

注意:

1. awk在打印變量時, 不用加`$`符合. 位置變量除外

范例: 打印1-100的和

[root@demo-c8 opt]# awk -v i=1 -v sum=0 'BEGIN{while (i<=100){sum+=i; i++};print sum}'
5050

2.4 循環do-while

語法:

do {statement;…}while(condition)

意義: 無論真假,至少執行一次循環體

do-while循環

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

范例:

[root@demo-c8 opt]# awk 'BEGIN{ total=0;i=1;do{ total+=i;i++;}while(i<=100);print total}'
5050

2.5 循環for

語法:

for(expr1;expr2;expr3) {statement;…}

常見用法:

for(variable assignment;condition;iteration process) {for-body}

特殊用法:能夠遍歷數組中的元素

范例: awk的for循環, 打印1-100

[root@demo-c8 opt]# awk 'BEGIN{for(i=1;i<=100;i++){print i}}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

范例: awk的for循環, 計算1-100的和

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

范例: awk, Shell, bc效率對比, 計算1+...+1000000的和

[root@demo-c8 opt]# time (awk 'BEGIN{sum=0;for(i=1;i<=1000000;i++){sum+=i};print sum}')
500000500000

real    0m0.079s
user    0m0.076s
sys 0m0.003s
[root@demo-c8 opt]# time (sum=0; for((i=1;i<=1000000;i++));do let sum+=i;done;echo $sum)
500000500000

real    0m5.446s
user    0m5.408s
sys 0m0.000s
[root@demo-c8 opt]# time (seq -s+ 1000000 |bc)
500000500000

real    0m0.432s
user    0m0.343s
sys 0m0.150s

2.6 continue和break

continue 中斷本次循環
break 中斷整個循環

格式:

continue [n]
break [n]

范例: continue, 打印1-100奇數的和

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

范例: break, 打印1-49

[root@demo-c8 opt]# awk 'BEGIN{for(i=1;i<=100;i++){if (i<=50){break}else{print i}}}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

2.7 next

next 可以提前結束對本行處理而直接進入下一行處理(awk自身循環)

范例: 打印UID是奇數的用戶名和UID

[root@demo-c8 opt]# awk -F":" '{if($3%2!=0)printf "%-20s %s\n", $1,$3}' /etc/passwd
bin                  1
adm                  3
sync                 5
halt                 7
operator             11
dbus                 81
systemd-coredump     999
systemd-resolve      193
tss                  59
geoclue              997
pulse                171
qemu                 107
usbmuxd              113
unbound              995
chrony               993
pipewire             991
radvd                75
clevis               983
cockpit-wsinstance   981
flatpak              979
rpcuser              29
gnome-initial-setup  977

3. 數組

awk的數組都是關聯數組

格式:

array_name[index-expression]

范例:

[root@demo-c8 opt]# weekdays["mon"]="monday"
[root@demo-c8 opt]# echo ${weekdays["mon"]}
monday

index-expression

  • 利用數組,實現 k/v 功能
  • 可使用任意字符串;字符串要使用雙引號括起來
  • 如果某數組元素(key)事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為空串("")
  • 若要判斷數組中是否存在某元素,要使用index in array格式進行遍歷. 存在返回1, 不存在返回0

注意: awk的關聯數組不支持[*], 取全部值

[root@demo-c8 opt]# awk 'BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";weekdays["wed"]="wednesday";print weekdays["mon"]}'
monday

范例: 判斷數組是否包含某個key

[root@demo-c8 opt]# awk 'BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";weekdays["wed"]="wednesday";print "thur" in weekdays; print "mon" in weekdays}'
0
1

若要遍歷數組中的每個value, 可以使用for循環. for循環每次遍歷時, 會取出數組的key.

范例:

[root@demo-c8 opt]# awk 'BEGIN{user["name"]="root"; user["uid"]="0"; user["password"]="Y"; for(i in user){print user[i]}}'
Y
root
0

范例: 顯示主機的連接狀態出現的次數, 并排序

  • ss命令輸出格式
[root@demo-c8 opt]# ss -nta | awk 'NR!=1{print $1}' | sort | uniq -c
      1 ESTAB
      7 LISTEN
  • state[$1]++: 創建一個awk數組, 名字為state. 按照$1, 把不同的狀態, 作為數組的key, ++表示分別按照不同的狀態, 進行次數累計. 最后得到的數組就是每個狀態對應的次數
[root@demo-c8 opt]# ss -ant | awk 'NR!=1{state[$1]++}END{for(i in state){print i,state[i]}}'
LISTEN 7
ESTAB 1

范例: 統計訪問網站的ip的次數

[root@demo-c8 opt]# cat access_log | head -n1
172.18.118.91 - - [20/May/2018:08:09:59 +0800] "GET / HTTP/1.1" 200 912 "-" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
[root@demo-c8 opt]# awk '{ip[$1]++}END{for(i in ip){printf "%-20s %s\n", ip[i],  i}}' access_log  | sort -nr | head -n5
4870                 172.20.116.228
3429                 172.20.116.208
2834                 172.20.0.222
2613                 172.20.112.14
2267                 172.20.0.227

范例: 利用/etc/hosts.deny文件拒絕其他服務器的SSH訪問

  • /etc/hosts.deny文件利用的是tcpwrapper技術, 但是僅在CentOS7和較老版本生效, CentOS8開始不支持
[20:10:41 root@centos-7-6 ~]#echo "sshd: 10.0.0.108" >> /etc/hosts.deny 
[root@demo-c8 opt]# ssh root@10.0.0.187
kex_exchange_identification: read: Connection reset by peer

4. awk函數

awk 的函數分為內置和自定義函數

4.1 常見內置函數

數值處理:

  • rand():返回0和1之間一個隨機數
  • srand():配合rand() 函數,生成隨機數的種子
  • int():返回整數部分

范例: rand()和srand()要配套使用, 否則rand()只會返回固定數值. 并且, 此命令不能執行過快, 否則只會返回相同的值

[22:42:27 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.482749
[22:42:40 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.12631
[22:42:42 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.12631
[22:42:42 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.12631
[22:42:42 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.0949145
[22:42:44 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.0949145
[22:42:44 root@centos7 ~]#awk 'BEGIN{srand();print rand()}'
0.25884

范例: 打印100以內整數十次

[22:45:52 root@centos7 ~]#awk 'BEGIN{srand();for(i=1;i<=10;i++)print int(rand()*100)}'
13
5
63
15
36
82
91
33
86
31

字符串處理:

  • length([s]):返回指定字符串的長度
  • sub(r,s,[t]):對t字符串搜索r表示模式匹配的內容,并將第一個匹配內容替換為s

范例: sub字符替換

[22:46:11 root@centos7 ~]#echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
2008-08:08 08:08:08
[22:47:26 root@centos7 ~]#echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",$1);print $0}'
2008-08:08 08:08:08
  • gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容

范例:

[22:48:10 root@centos7 ~]#echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
2008-08-08 08-08-08
[22:49:00 root@centos7 ~]#echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",$0);print $0}'
2008-08-08 08-08-08

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

范例:

[22:49:47 root@centos7 ~]#netstat -nt | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}'
192.168.192.1 1

system 函數:可以awk中調用shell命令

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

[22:50:43 root@centos7 ~]#awk 'BEGIN{system("hostname")}'
centos7.mac
[22:50:48 root@centos7 ~]#awk 'BEGIN{score=100; system("echo your score is " score) }'
your score is 100

范例: 統計連接次數大于等于10的ip, 并且添加到iptables

[root@centos8 ~]#netstat -tn | awk 
'/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count){if(count[i]>=10)
{system("iptables -A INPUT -s "i" -j REJECT")}}}'

4.2 自定義函數

自定義函數格式:

function name ( parameter, parameter, ... ) {
   statements
   return expression
}

范例: 統計兩個數誰大誰小

[22:53:20 root@centos7 ~]#vim func.awk

function max(x,y) {                                                             
 x>y?var=x:var=y
 return var
}
BEGIN{print max(a,b)}
[22:53:52 root@centos7 ~]#awk -v a=30 -v b=20 -f func.awk
30

5. awk腳本

  • 將awk程序寫成腳本,直接調用或執行

范例:

[22:56:52 root@centos7 ~]#vim passwd.awk

{if($3<=1000)print $1,$3}
[22:57:20 root@centos7 ~]#awk -F: -f passwd.awk /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
tcpdump 72

范例:

[22:57:21 root@centos7 ~]#vim test.awk

#!/bin/awk -f
#this is a awk script
{if($3<=1000)print $1,$3}  
[22:58:45 root@centos7 ~]#./test.awk -F: /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
sshd 74
postfix 89
tcpdump 72
  • 向awk腳本傳遞參數

格式:

awkfile var=value var2=value2... Inputfile

注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用。可以通過-v 參數,讓awk在執行BEGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數

范例:

[22:58:46 root@centos7 ~]#vim test2.awk
#!/bin/awk -f
{if($3 >=min && $3<=max)print $1,$3}    
[23:00:17 root@centos7 ~]#chmod +x test2.awk
[23:00:18 root@centos7 ~]#./test2.awk -F: min=100 max=200 /etc/passwd
systemd-network 192

練習:

1、文件host_list.log 如下格式,請提取”.magedu.com”前面的主機名部分并寫入到回到該文件中

1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
......
999 study.magedu.com

2、統計/etc/fstab文件中每個文件系統類型出現的次數
3、統計/etc/fstab文件中每個單詞出現的次數
4、提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有數字
5、有一文件記錄了1-100000之間隨機的整數共5000個,存儲的格式100,50,35,89…請取出其中最大和最小的整數
6、解決Dos攻擊生產案例:根據web日志或者或者網絡連接數,監控當某個IP并發連接數或者短時內PV達到100,即調用防火墻命令封掉對應的IP,監控頻率每隔5分鐘。防火墻命令為:iptables -A INPUT -s IP -j REJECT
7、將以下文件內容中FQDN取出并根據其進行計數從高到低排序

http://mail.magedu.com/index.html
http://www.magedu.com/test.html
http://study.magedu.com/index.html
http://blog.magedu.com/index.html
http://www.magedu.com/images/logo.jpg
http://blog.magedu.com/20080102.html
http://www.magedu.com/images/magedu.jpg

參考答案:

[root@centos8 ~]#awk -F"/" '{url[$3]++}END{for(i in url){print url[i],i}}' 
url.log |sort -nr
3 www.magedu.com
2 blog.magedu.com
1 study.magedu.com
1 mail.magedu.com

8、將以下文本以inode為標記,對inode相同的counts進行累加,并且統計出同一inode中,beginnumber的最小值和endnumber的最大值

inode|beginnumber|endnumber|counts|
106|3363120000|3363129999|10000|
106|3368560000|3368579999|20000|
310|3337000000|3337000100|101|
310|3342950000|3342959999|10000|
310|3362120960|3362120961|2|
311|3313460102|3313469999|9898|
311|3313470000|3313499999|30000|
311|3362120962|3362120963|2|

輸出的結果格式為:

310|3337000000|3362120961|10103|
311|3313460102|3362120963|39900|
106|3363120000|3368579999|30000|
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容