文本處理工具awk

来源:https://www.cnblogs.com/www233ii/archive/2019/11/06/11808999.html
-Advertisement-
Play Games

文本處理工具awk awk:(Aho, Weinberger, Kernighan,)報告生成器,格式化文本輸出 有多種版本:New awk(nawk),GNU awk( gawk) @[toc] gawk:模式掃描和處理語言 awk語言 ⽣成需要的測試數據: [root@magedu ~] hea ...


目錄

文本處理工具awk

awk:(Aho, Weinberger, Kernighan,)報告生成器,格式化文本輸出
有多種版本:New awk(nawk),GNU awk( gawk)

gawk:模式掃描和處理語言

1. 基本用法:  
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 通常是被放在單引號中  
2. 選項:  
-F “分隔符” 指明輸入時用到的欄位分隔符  
-v var=value 變數賦值   

awk語言

1. 基本格式:awk [options] 'program' file…
Program:pattern{action statements;..}
pattern和action
• pattern部分決定動作語句何時觸發及觸發事件
BEGIN,END
• action statements對數據進行處理,放在{}內指明
print, printf
2. 分割符、域和記錄
• awk執行時,由分隔符分隔的欄位(域)標記$1,$2...$n稱為域標識。$0
3. 為所有域,註意:此時和shell中變數$符含義不同
• 文件的每一行稱為記錄
• 省略action,則預設執行 print $0 的操作  

⽣成需要的測試數據: [root@magedu ~]# head -10 /etc/passwd > awktest.txt

awk省略action,預設執⾏print $0
[root@centos7 ~]#head -10 /etc/passwd > /data/awktest.txt
[root@centos7 ~]#cd
[root@centos7 ~]#cd /data
[root@centos7 data]#ls
awktest.txt  test  vimrc.txt  YYYY13.sh
[root@centos7 data]#awk '{print}' awktest.txt 
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  

awk工作原理

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

【例1】BEGIN的使⽤:  
[root@centos7 data]#awk '{print 2.5*3}' awktest.txt 
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
7.5
[root@centos7 data]#awk 'BEGIN{print 2.5*3}' awktest.txt 
7.5
[root@centos7 data]#awk 'BEGIN{print 2.5*3}' 
7.5

print

print格式:print item1, item2, ...
#要點:

(1) 逗號分隔符

(2) 輸出item可以字元串,也可是數值;當前記錄的欄位、變數或awk的表達式

(3) 如省略item,相當於print $0

 #示例:
awk '{print "hello,awk"}'
awk –F: '{print}' /etc/passwd
awk –F: ‘{print “wang”}’ /etc/passwd
awk –F: ‘{print $1}’ /etc/passwd
awk –F: ‘{print $0}’ /etc/passwd
awk –F: ‘{print $1”\t”$3}’ /etc/passwd
grep “^UUID”/etc/fstab | awk ‘{print $2,$4}’    

【例1】指定:(冒號)為分隔符,列印每⾏記錄的第⼀個欄位即輸出$1
[root@centos7 data]#awk -F: '{print $1}' awktest.txt 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator    

【例2】同理再把第三個欄位輸出,輸出前添加三個連字元(---):  
[root@centos7 data]#awk -F: '{print $1"---"$3}' awktest.txt 
root---0
bin---1
daemon---2
adm---3
lp---4
sync---5
shutdown---6
halt---7
mail---8
operator---11  

【例3】取出磁碟使⽤率
[root@centos7 data]#df
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda2      104806400  4543708 100262692   5% /
devtmpfs          998216        0    998216   0% /dev
tmpfs            1014056        0   1014056   0% /dev/shm
tmpfs            1014056    10148   1003908   2% /run
tmpfs            1014056        0   1014056   0% /sys/fs/cgroup
/dev/sda3       52403200    35036  52368164   1% /data
/dev/loop0      10491772 10491772         0 100% /mnt
/dev/sda1        1038336   167036    871300  17% /boot
tmpfs             202812        0    202812   0% /run/user/0  
  
[root@centos7 data]#df |grep "^/dev"|awk -F" +|%" NR!=1'{print $5}'
1
100
17

[root@centos7 data]#df |awk -F" +|%" '{print $5}'
Use
5
0
0
2
0
1
100
17
0
第一行去除寫法。
[root@centos7 data]#df |awk -F" +|%" NR!=1'{print $5}'
5
0
0
2
0
1
100
17
0

awk變數

變數:內置和自定義變數

FS:輸入欄位分隔符,預設為空白字元  
awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
awk –F: '{print $1,$3,$7}' /etc/passwd  

【例】 輸⼊欄位分隔符FS變數的使⽤  
[15:14:02 root@centos6 ~]#awk -v FS=':' '{print$1,FS,$3}' /data/awktest
root : 0
bin : 1
daemon : 2
adm : 3
lp : 4
sync : 5
shutdown : 6
halt : 7
mail : 8
uucp : 10  
OFS:輸出欄位分隔符,預設為空白字元
awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd  

【例】輸⼊出欄位分隔符OFS變數的使⽤   
[15:14:17 root@centos6 ~]#awk -v FS=':' -v OFS='----' '{print $1,$3,$7}
root----0----/bin/bash
bin----1----/sbin/nologin
daemon----2----/sbin/nologin
adm----3----/sbin/nologin
lp----4----/sbin/nologin
sync----5----/bin/sync
shutdown----6----/sbin/shutdown
halt----7----/sbin/halt
mail----8----/sbin/nologin
uucp----10----/sbin/nologin
RS:輸入記錄分隔符,指定輸入時的換行符
awk -v RS=' ' ‘{print }’ /etc/passwd  

【例】輸⼊記錄分隔符RS變數的使⽤  
[15:17:48 root@centos6 data]#awk -v RS=':' '{print}' /data/awktest.txt 
root
x
0
0
root
/root
/bin/bash
bin
x
1
1
bin
/bin
/sbin/nologin
.
.
.
.(省略)
.
.
.
.
mail
x
8
12
mail
/var/spool/mail
/sbin/nologin
uucp
x
10
14
uucp
/var/spool/uucp
/sbin/nologin
ORS:輸出記錄分隔符,輸出時用指定符號代替換行符
awk -v RS=' ' -v ORS='###' '{print $0}' /etc/passwd  
【例】輸出記錄分隔符ORS變數的使⽤(這裡我試了一下有好多種用法我演示3種)  
[15:19:10 root@centos6 data]#awk -v RS=':' -v ORS='-----' '{print}' /da
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
uucp-----x-----10-----14-----uucp-----/var/spool/uucp-----/sbin/nologin
-----   (這裡可以以冒號為分隔符用ORS替換掉)    

[15:26:32 root@centos6 daawk  -v OR=' ' -v ORS='----' '{print}' /data/a
root:x:0:0:root:/root:/bin/bash----bin:x:1:1:bin:/bin:/sbin/nologin-------lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin----sync:x:5:0:sync:/sbin:/b:/sbin/halt----mail:x:8:12:mail:/var/spool/mail:/sbin/nologin----uucp:x
[15:27:40 root@centos6 data]#awk -v ORS='----' '{print}' /data/awktest.
root:x:0:0:root:/root:/bin/bash----bin:x:1:1:bin:/bin:/sbin/nologin-------lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin----sync:x:5:0:sync:/sbin:/b:/sbin/halt----mail:x:8:12:mail:/var/spool/mail:/sbin/nologin----uucp:x 
(這裡OR加不加都一樣的效果)
    
[15:25:06 root@centos6 data]#awk  -v RS=':' -v ORS='----\n' '{print}' /
root----
x----
0----
0----
root----
/root----
/bin/bash
bin----
x----
1----
1----
bin----
/bin----
/sbin/nologin
daemon----
x----
2----
2----
daemon----
/sbin----
/sbin/nologin       (這就是回車換行的意思)
NF:欄位數量
awk -F:'{print NF}' /etc/fstab 引用變數時,變數前不需加$
awk -F:'{print $(NF-1)}' /etc/passwd   
【例】欄位數量NF變數的使⽤  
[15:29:39 root@centos6 data]#awk -F: '{print NF}' awktest.txt 
7
7
7
7
7
7
7
7
7
7  
[15:30:25 root@centos6 data]#awk -F: '{print $(NF-1)}' awktest.txt 
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
/var/spool/mail
/var/spool/uucp
NR:記錄號
 awk '{print NR}' /etc/fstab ; awk END '{print NR}' /etc/fstab  

【例】⾏號NR變數的使⽤  
[15:32:33 root@centos6 data]#awk -F: '{print NR,$1}' awktest.txt 
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
10 uucp
FNR:各文件分別計數,記錄號
awk '{print FNR}' /etc/fstab /etc/inittab  
  
【例】各⽂件分別的記錄號FNR變數的使⽤  
[15:32:39 root@centos6 data]#awk '{print FNR,$1}' /etc/fstab /data/awkt
1 
2 #
3 #
4 #
5 #
6 #
7 #
8 #
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin  
FILENAME:當前文件名
awk '{print FILENAME}' /etc/fstab  
  
【例】當前⽂件名FILENAME變數的使⽤  
[15:34:03 root@centos6 data]#awk '{print FILENAME,FNR,$1}' /etc/fstab /
/etc/fstab 1 
/etc/fstab 2 #
/etc/fstab 3 #
/etc/fstab 4 #
/etc/fstab 5 #
/etc/fstab 6 #
/etc/fstab 7 #
/etc/fstab 8 #
/data/awktest.txt 1 root:x:0:0:root:/root:/bin/bash
/data/awktest.txt 2 bin:x:1:1:bin:/bin:/sbin/nologin
/data/awktest.txt 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
/data/awktest.txt 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
/data/awktest.txt 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
/data/awktest.txt 6 sync:x:5:0:sync:/sbin:/bin/sync
/data/awktest.txt 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
/data/awktest.txt 8 halt:x:7:0:halt:/sbin:/sbin/halt
/data/awktest.txt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
/data/awktest.txt 10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin  
ARGC:命令行參數的個數
awk '{print ARGC}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGC}' /etc/fstab /etc/inittab  

【例】命令⾏參數的個數ARGC變數的使⽤ 
[15:35:37 root@centos6 data]#awk 'BEGIN{print ARGC}' /etc/fstab /data/awktest.txt 
3
[15:47:06 root@centos6 data]#awk 'BEGIN{print ARGC}' /etc/fstab /data/awktest.txt /etc/shadow
4  
ARGV:數組,保存的是命令行所給定的各參數
awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab  

【例】命令⾏給定的各參數的數組ARGV變數的使⽤  
[16:42:16 root@centos6 data]#awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/inittab 
/etc/fstab
[16:42:22 root@centos6 data]#awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/inittab 
/etc/inittab
[16:42:41 root@centos6 data]#awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/inittab 
awk

自定義變數

自定義變數(區分字元大小寫)

(1) -v var=value

(2) 在program中直接定義
示例:
awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello,gawk";print test}'
awk -F: '{sex=“male”;print $1,sex,age;age=18}' /etc/passwd
cat awkscript
{print script,$1,$2}
awk -F: -f awkscript script="awk" /etc/passwd

【例1】命令⾏給定的各參數的數組ARGV變數的使⽤  
[17:03:28 root@centos6 data]#awk -F: -v name='username:' '{print name,$1}' awktest.txt 
username: root
username: bin
username: daemon
username: adm
username: lp
username: sync
username: shutdown
username: halt
username: mail
username: uucp 

或變數定義在program⾥⾯為: 
awk -F: '{name="username:";print name,$1}' awktest.txt    

或在shell中定義了變數,在awk中⾃定義的變數調⽤shell中的變數:
username="username"; awk -F: -v name=$username: '{print name,$1}' awktest.txt  
  
【例2】把awk執⾏命令放⼊⼀個⽂件中,直接調⽤awk腳本⽂件  
[17:07:41 root@centos6 data]#echo '{name="magedu";age=20;print name,$1,age}' > awkscript
[17:11:19 root@centos6 data]#awk -F: -f awkscript awktest.txt 
magedu root 20
magedu bin 20
magedu daemon 20
magedu adm 20
magedu lp 20
magedu sync 20
magedu shutdown 20
magedu halt 20
magedu mail 20
magedu uucp 20

printf命令

格式化輸出:printf “FORMAT”, item1, item2, ...

(1) 必須指定FORMAT

(2) 不會自動換行,需要顯式給出換行控制符,\n

(3) FORMAT中需要分別為後面每個item指定格式符
格式符:與item一一對應
%c:顯示字元的ASCII碼
%d, %i:顯示十進位整數
%e, %E:顯示科學計數法數值
%f:顯示為浮點數
%g, %G:以科學計數法或浮點形式顯示數值
%s:顯示字元串
%u:無符號整數
%%:顯示%自身

修飾符
#[.#] 第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f

  • 左對齊(預設右對齊) %-15s
  • 顯示數值的正負符號 %+d
【例1】格式化輸出,以冒號為分隔符,第⼀個欄位寬度20個字元串,第⼆個欄位寬度10個數⼦,⼀⾏輸出2個欄位,然後換⾏  
[18:49:57 root@centos6 data]#awk -F: '{printf "%20s %10d\n",$1,$3}' awktest.txt 
               root          0
                bin          1
             daemon          2
                adm          3
                 lp          4
               sync          5
           shutdown          6
               halt          7
               mail          8
               uucp         10
註意:(預設輸出是右對齊)  

【例2】接上例,格式化輸出為左對齊  
[18:54:11 root@centos6 data]#awk -F: '{printf "%-20s %10d\n",$1,$3}' awktest.txt 
root                          0
bin                           1
daemon                        2
adm                           3
lp                            4
sync                          5
shutdown                      6
halt                          7
mail                          8
uucp                         10
 
【例3】以冒號為分隔符,每⾏輸出”username:第⼀個欄位“,然後換⾏  
[18:55:46 root@centos6 data]#awk -F: '{printf "username:%s\n",$1}' awktest.txt 
username:root
username:bin
username:daemon
username:adm
username:lp
username:sync
username:shutdown
username:halt
username:mail
username:uucp
 
【例4】以冒號為分隔符,每⾏輸出”username:第⼀個欄位,左對齊,占20個寬度,UID:第三個欄位“,然後換⾏  
[18:58:26 root@centos6 data]#awk -F: '{printf "username:%-20s uid:%d\n",$1,$3}' awktest.txt 
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:uucp                 uid:10

awk操作符

  1. 算術操作符:
    x+y:加法;
    x-y:減法;
    x*y:乘法;
    x/y:除法;
    x^y:冪運算;
    x%y:取模(餘數)
    -x:轉換為負數
    +x:將字元串轉換為數值

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

  3. 賦值操作符:
    =:右邊賦值給左邊;
    +=:先加,再賦值;
    -=:先減,再賦值;
    *=:先乘,再賦值;
    /=:先除,再賦值;
    %=:先取餘,再賦值;
    ^=:先冪運算,再賦值;
    ++:遞增操作;
    --:遞減操作。
    下麵兩語句有何不同
    • awk 'BEGIN{i=0;print ++i,i}'
    • awk 'BEGIN{i=0;print i++,i}'

  4. 比較操作符:
    ==:判斷相等;
    !=:判斷不等;
    >:判斷大於;
    >=:判斷大於等於;
    <:判斷小於;
    <=:判斷小於等於

  5. 模式匹配符:
    ~:左邊是否和右邊匹配包含;
    !~:是否不匹配。

  6. 邏輯操作符:
    邏輯與&&,
    邏輯或||,
    邏輯非!

awk PATTERN:(awk的模式)
PATTERN:根據pattern條件,過濾匹配的行,再做處理:

  1. 如果未指定:空模式,匹配每一行;
  2. /regular expression/:僅處理能夠模式匹配到的行,需要用//擴起來;
  3. relational expression:關係表達式,結果為真,才會被處理;
    真:結果為非0值,非空字元串都是真;
    假:結果為空字元串或0值都是假。
  4. line ranges:行範圍;
    startine,endline:/pat1/,/pat2/不支持直接給出數子格式。
  5. BEGIN/END模式
    BEGIN{}:僅在開始處理文件中的文本之前執行一次;
    END{}:僅在文本處理完成之後執行一次。

awk的action:常⽤的action分類

  1. Expression:算術,比較表達式等;
  2. Control statuments:if,while等;
  3. conmpound statements:組合語句;
  4. input statements:
  5. output statements:print等。

函數調⽤:
funciton_name(argu1,argu2,...)

1、awk使⽤算術操作符

    【例1】使⽤awk的算術操作符,計算2*3  
    [18:58:30 root@centos6 data]#awk 'BEGIN{print 2*3}'
6  

    【例2】使⽤awk的算術操作符,取模5%2  
    [19:21:12 root@centos6 data]#awk 'BEGIN{print 5%2}'
1  

2、awk賦值操作符

    【例1】使⽤awk的+=賦值操作符  
    [19:21:25 root@centos6 data]#awk 'BEGIN{i=10;print i+=1}'
11  

    【例2】使⽤awk的i++賦值操作符  
    [19:29:05 root@centos6 data]#awk 'BEGIN{i=10;print i++}'
10  

    【例3】使⽤awk的++i賦值操作符  
    [19:32:58 root@centos6 data]#awk 'BEGIN{i=10;print ++i}'
11
[19:33:17 root@centos6 data]#awk 'BEGIN{i=10;print ++i;print i}'
11
11
[19:33:27 root@centos6 data]#awk 'BEGIN{i=10;print ++i,i}'
11 11  

    【例4】各種賦值操作符使用。(使用方法很多主要看你做什麼。) 
[19:33:30 root@centos6 data]#awk 'BEGIN{i=10;print --i,i}'
9 9
[19:34:18 root@centos6 data]#awk 'BEGIN{i/=10;print --i,i}'
-1 -1
[19:34:52 root@centos6 data]#awk 'BEGIN{i%=10;print --i,i}'
-1 -1
[19:35:15 root@centos6 data]#awk 'BEGIN{i^=10;print --i,i}'
-1 -1
[19:35:25 root@centos6 data]#awk 'BEGIN{i^=10;print ++i,i}'
1 1
[19:35:38 root@centos6 data]#awk 'BEGIN{i-=10;print ++i,i}'
-9 -9
[19:35:46 root@centos6 data]#awk 'BEGIN{i-=10;print --i,i}'
-11 -11
[19:36:35 root@centos6 data]#awk 'BEGIN{i=10;print i-=1}'
9
[19:36:38 root@centos6 data]#awk 'BEGIN{i=10;print i/=1}'
10
[19:38:37 root@centos6 data]#awk 'BEGIN{i=10;print i*=1}'
10

3、awk中的模式匹配符

    【例1】匹配包含root⾏的記錄  
[19:38:48 root@centos6 data]#awk -F: '$0 ~ /root/{print $0}' awktest.txt 
root:x:0:0:root:/root:/bin/bash  

[19:47:23 root@centos6 data]#awk -F: '$3==0' awktest.txt 
root:x:0:0:root:/root:/bin/bash    (uid為0的不指定欄位預設列印出來) 

[19:48:43 root@centos6 data]#awk -F: '$0~ "^root"' awktest.txt 
root:x:0:0:root:/root:/bin/bash    
  
    【例2】匹配不包含root⾏的記錄
[19:47:16 root@centos6 data]#awk -F: '$1 !~ /root/{print $0}' awktest.txt 
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
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
  
    【例3】⽤正則表達式匹配包含root⾏的記錄  
[20:01:04 root@centos6 data]#awk -F: '$0 ~ /^root/{print $0}' awktest.txt 
root:x:0:0:root:/root:/bin/bash    

    【例4】顯⽰硬碟分區的使⽤率
[20:08:20 root@centos6 data]#df -h |awk '$0 ~ /^\/dev\/sd/{print $1,$5}'
/dev/sda2 4%
/dev/sda1 4%
/dev/sda3 1%
  
    【例5】從hostname.txt⽂件中,提取功能變數名稱的第⼀部分  
[20:14:09 root@centos6 data]#cat hostname.txt 
magedu.com.com
www.magedu.com
mail.magedu.com
[20:14:20 root@centos6 data]#awk -F'[.| ]' '{print $(NF-2)}' hostname.txt 
magedu
www
mail

4、awk的邏輯操作符

    【例1】顯⽰第三欄位⼤於等於0,且⼩於等於1000的⾏中的第1欄位  
[20:26:42 root@centos6 data]#awk -F: '$3>=0 && $3<=1000{print  $1}' /etc/passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
.
.
.
.
haldaemon
ntp
apache
saslauth
postfix
gdm
pulse
sshd
tcpdump  

    【例2】顯⽰第三欄位等於0,或⼤於等於1000的⾏中的第1欄位  
[20:28:59 root@centos6 data]#awk -F: '$3==0 || $3>=1000{print $1}' /etc/passwd
root
nfsnobody   

    【例3】顯⽰除了第三段等於0的⾏中的第1欄位
[20:29:57 root@centos6 data]#awk -F: '!($3==0){print $1}' /etc/passwd
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
games
gopher
ftp
nobody
dbus
usbmuxd
rpc  

    【例4】awk實現列印奇數⾏和偶數⾏
[20:31:47 root@centos6 data]#seq 10 |awk '!(i=!i)'
2
4
6
8
10
[20:33:41 root@centos6 data]#seq 10 |awk 'i=!i'
1
3
5
7
9
等同於sed命令:  
[20:33:52 root@centos6 data]#seq 10 |sed -n '1~2p'
1
3
5
7
9
[20:34:59 root@centos6 data]#seq 10 |sed -n '2~2p'
2
4
6
8
10  

5、awk的PATTERN使⽤

    【例1】查找/etc/passwd⽂件中,以r開頭的⾏,顯⽰第1欄位和第3欄位  
[20:35:04 root@centos6 data]#awk -F: '/^r/{print $1,$3}' /etc/passwd
root 0
rpc 32
rtkit 499
rpcuser 29  

    【例2】查找netstat -nt命令的結果中Foreign Address列的地址,並顯⽰  
[20:38:03 root@centos6 data]#netstat -nt |awk '/^tcp/{print $5}'|awk -F: '{print $1}'
192.168.39.1  

    【例3】查找netstat -nt命令的結果中Foreign Address列的地址,統計每個地址鏈接的次數  
[20:38:49 root@centos6 data]#netstat -nt |awk '/^tcp/{print $5}'|awk -F: '{print $1}'|sort|uniq -c
      1 192.168.39.1  

    【例4】匹配以f開頭的⾏開始,到r開頭的⾏結束之間的所有⾏  
[20:40:44 root@centos6 data]#awk '/^f/,/^r/' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin  
   註意:如果沒有⼀r開頭的⾏,則會從匹配的以f開頭的⾏開始,到最後都顯⽰。   

6、BRGIN/END模式

【例】awk的BEGIN/END模式的使⽤  
[20:52:49 root@centos6 data]#awk -F: 'BEGIN{print "user               id\n*********************"}{printf "%-10s|%10d\n", $1,$3}END{print "*********************\n over"}' awktest.txt 
user               id
*********************
root      |         0
bin       |         1
daemon    |         2
adm       |         3
lp        |         4
sync      |         5
shutdown  |         6
halt      |         7
mail      |         8
uucp      |        10
*********************
 over

awk的條件判斷

掌握awk的條件判斷。
條件表達式:(三目表達式)
selector?if-true-expression:if-false-expression

控制語句:
{statements;...}:組合語句;
if(condition){statements;...}else {statements;...}
if(condition1){statement1}else if(condition2){statement2}
else{statement3}
while(condition){statements;...}
do {statements;...} while(condition)
for(expr1;expr2;expr3) {statements;...}
break
continue
delete array[index]
delete array
exit

1、awk條件表達式的使⽤

 【例1】顯⽰uid⼤於等於500,輸出common user,⽤戶名和uid,否則輸出sysuser  
 [20:52:56 root@centos6 data]#awk -F: '{$3>=500?usertype="common user":usertype="sysuser";printf "%-15s %-20s %10d\n",usertype,$1,$3}' /etc/passwd
sysuser         root                          0
sysuser         bin                           1
sysuser         daemon                        2
sysuser         adm                           3
sysuser         lp                            4
sysuser         sync                          5
sysuser         shutdown                      6
sysuser         halt                          7
sysuser         mail                          8
sysuser         uucp                         10
sysuser         operator                     11
sysuser         games                        12
sysuser         gopher                       13
sysuser         ftp                          14
sysuser         nobody                       99
sysuser         dbus                         81
sysuser         usbmuxd                     113
sysuser         rpc                          32
sysuser         rtkit                       499
sysuser         avahi-autoipd               170
sysuser         vcsa                         69
sysuser         abrt                        173
sysuser         rpcuser                      29
common user     nfsnobody                 65534
sysuser         haldaemon                    68
sysuser         ntp                          38
sysuser         apache                       48
sysuser         saslauth                    498
sysuser         postfix                      89
sysuser         gdm                          42
sysuser         pulse                       497
sysuser         sshd                         74
sysuser         tcpdump                      72
common user     yang                        500  
【例2】查找netstat -nt命令的結果中Foreign Address列的地址,統計每個地址鏈接的次數,如果⼤於2次,顯⽰ip  
[21:07:46 root@centos6 data]#netstat -nt |awk '/^tcp/{print $5}'|awk -F: '{print $1}'|sort|uniq -c |awk '$1>1{print $2}'
192.168.39.120  
【例3】模擬併發訪問http服務,查找ip連接次數超過200次的訪問ip地址 模擬併發:  
[root@magedu ~]# yum -y install httpd-tools
[root@magedu ~]# ab -c 10 -n 200 http://172.18.120.26/    
這裡要記得打開httpd服務,然後確保你的seliunx和防火牆關閉。
[21:22:58 root@centos6 data]#service httpd status
httpd is stopped
[21:23:56 root@centos6 data]#service httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for centos6.10yang.com
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
顯⽰超過200次訪問的ip:  (有兩種方法)  

[21:24:36 root@centos6 data]#awk '{print $1}' /var/log/httpd/access_log|sort|uniq -c
    207 192.168.39.6
[21:24:39 root@centos6 data]#awk '{print $1}' /var/log/httpd/access_log|sort|uniq -c|awk '$1>200{print $2}'
192.168.39.6  
【例4】顯⽰第10條到第20條記錄的第1欄位  
[21:29:44 root@centos6 data]#awk -F: '(NR>=10 && NR<=20){print NR,$1}' /etc/passwd
10 uucp
11 operator
12 games
13 gopher
14 ftp
15 nobody
16 dbus
17 usbmuxd
18 rpc
19 rtkit
20 avahi-autoipd  

註意:顯⽰從第10⾏到第20⾏內容,也可⽤sed命令實現:  
[21:33:49 root@centos6 data]#sed -n '10,20p' /etc/passwd
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin

2、awk組合語句

【例】以冒號為分隔符,分別列印第1欄位和第3欄位
[19:30:23 root@centos6 ~]#awk -F: '{print $1;print $3}' /data/awktest.txt 
root
0
bin
1
daemon
2
adm
3
lp
4
sync
5
shutdown
6
halt
7
mail
8
uucp
10
[19:35:36 root@centos6 ~]#awk -F: '{print $1, $3}' /data/awktest.txt 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
    (組合語句和後面的寫法還是不同的,組合會換行。)  

3、if-else語句:對awk取得的整⾏或某欄位做條件判斷

【例1】對第3欄位判斷⼤於等於500,則顯⽰每⾏的用戶名和UID。
[19:39:21 root@centos6 ~]#awk -F: '{if($3>=500)print $1,$3}' /etc/passwd
nfsnobody 65534
yang 500
  
【例2】查找最後⼀個欄位是/bin/bash的⾏,列印第⼀個欄位  
[19:42:52 root@centos6 ~]#awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd
root
yang
  
【例3】查找以空格為分隔符,顯⽰每⾏⼤於5個欄位所在的⾏
[19:46:12 root@centos6 ~]#awk '{if(NF>5) print $0}' /etc/fstab 
# Created by anaconda on Fri Sep 20 20:04:25 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
UUID=472ab1b1-b917-4e4f-8863-ff95e637dc61 /                       ext4    defaults        1 1
UUID=0deb1cfb-a4d0-4d7a-916d-b5e6a1e9002a /boot                   ext4    defaults        1 2
UUID=7c11fe6c-49e2-41ea-9464-c6be1e5187ec /data                   ext4    defaults        1 2
UUID=c2af0f43-08f3-45b8-976c-9a10a38f441f swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
  
【例4】查找第3欄位⼤於等500,則輸出Common user:第1欄位,否則輸出root or Sysuer:第1欄位  
[19:54:17 root@centos6 ~]#awk -F: '{if($3>=500){printf "Common user:%s\n",$1} else {printf"root or Sysuser:%s\n",$1}}' /etc/passwd
root or Sysuser:root
root or Sysuser:bin
root or Sysuser:daemon
root or Sysuser:adm
root or Sysuser:lp
root or Sysuser:sync
root or Sysuser:shutdown
root or Sysuser:halt
root or Sysuser:mail
root or Sysuser:uucp
root or Sysuser:operator
root or Sysuser:games
root or Sysuser:gopher
root or Sysuser:ftp
root or Sysuser:nobody
root or Sysuser:dbus
root or Sysuser:usbmuxd
root or Sysuser:rpc
root or Sysuser:rtkit
root or Sysuser:avahi-autoipd
root or Sysuser:vcsa
root or Sysuser:abrt
root or Sysuser:rpcuser
Common user:nfsnobody
root or Sysuser:haldaemon
root or Sysuser:ntp
root or Sysuser:apache
root or Sysuser:saslauth
root or Sysuser:postfix
root or Sysuser:gdm
root or Sysuser:pulse
root or Sysuser:sshd
root or Sysuser:tcpdump
Common user:yang
或:  
[19:56:54 root@centos6 ~]#awk -F: '{if($3>=500)printf "Common user:%s\n",$1;else printf "root or Sysuser:%s\n",$1}' /etc/passwd  
......
root or Sysuser:nobody
root or Sysuser:dbus
root or Sysuser:usbmuxd
root or Sysuser:rpc
root or Sysuser:rtkit
root or Sysuser:avahi-autoipd
root or Sysuser:vcsa
root or Sysuser:abrt
root or Sysuser:rpcuser
Common user:nfsnobody
root or Sysuser:haldaemon
root or Sysuser:ntp
......  
  
【例5】顯⽰磁碟使⽤率⼤於等於4%的分區   
[20:02:32 root@centos6 ~]#df -h |awk -F% '/^\/dev/{print $1}' |awk '$NF>=4{print $1,$5}'
/dev/sda2 4
/dev/sda1 4
  
【例6】判斷awk⾃定義變數test的值,⼤於90則顯⽰very good,⼤於60則顯⽰good,其它值顯⽰no pass  
[20:02:48 root@centos6 ~]#awk 'BEGIN{test=100;if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}'
very good
[20:05:53 root@centos6 ~]#awk 'BEGIN{test=89;if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}'
good
[20:06:40 root@centos6 ~]#awk 'BEGIN{test=59;if(test>90){print "very good"}else if(test>60){print "good"}else{print "no pass"}}'
no pass

awk的迴圈

掌握awk的迴圈。
while(condition){statement;...}
條件為真,進入迴圈,條件為假退出迴圈;
使⽤場景:對⼀⾏內的多個欄位逐⼀類似處理時使⽤;對數組中的各元素逐⼀處理時使⽤。

do-while迴圈語法:do {statement;...}while(condition)無論真假,至少執行一次迴圈體。
for迴圈語法:for(expr1;expr2;expr3){statement;...}

常見用法:
for(variable assignment;condition;iteration process
{for-body}

特殊用法:
能夠遍曆數組中的元素:for(var in array){for-body}

witch語句:
語法:switch(expresssion){case VALUE1 or /REGEXP/:statement1;case VALUE2 or
/REGEXP2/:statement2;...;default:statement}
break、continue、next語句:
break [n]:結束整個迴圈預設是最近的一次迴圈;
continue [n]:跳過本輪迴圈,執行下一輪迴圈;
next:提前結束對本行處理而直接進入下一行處理(awk自身迴圈)。

1、awk中使⽤while迴圈

【例1】統計第5⾏內容中每個單詞分別有多少個字元  
[20:37:30 root@centos6 ~]#awk '/ all/{i=1;while(i<=NF){print $i,length($i);++i}}' /etc/grub.conf 
# 1
all 3
kernel 6
and 3
initrd 6
paths 5
are 3
relative 8
to 2
/boot/, 7
eg. 3
[20:37:47 root@centos6 ~]#sed -n '5p' /etc/grub.conf 
#          all kernel and initrd paths are relative to /boot/, eg.
  
【例2】查找最⼤數和最⼩數  
[20:45:10 root@centos6 data]#awk -F, '{min=$1;max=$1;i=1;while(i<=NF){if(max<$i)max=$i;if(min>$i)min=$i;i++};print "max:"max,"min:"min}' num.txt
max:255 min:0
或使用shell命令實現:
[20:45:16 root@centos6 data]#for i in `tr ',' ' ' <num.txt`;do echo $i;done|sort -n|head
0
5
6
9
16
34
111
172
192
255
[20:47:48 root@centos6 data]#for i in `tr ',' ' ' <num.txt`;do echo $i;done|sort -n|head -1
0
[20:47:52 root@centos6 data]#for i in `tr ',' ' ' <num.txt`;do echo $i;done|sort -n|tail -1
255
  
【例3】計算1+2+3+...+100的和  
[20:58:18 root@centos6 data]#awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print "sum="sum}'
sum=5050 
使用shell命令實現:
[20:58:41 root@centos6 data]#sum=0;for i in {1..100};do let sum+=i; done;echo sum=$sum
sum=5050
  
【例4】awk中使⽤while迴圈計算10000內的總和  
[21:00:28 root@centos6 data]#awk 'BEGIN{i=1;sum=0;while(i<=10000){sum+=i;i++};print "sum="sum}'
sum=50005000

2、awk中使⽤do-while迴圈

【例】使⽤do-while計算100000內的和  
[21:06:43 root@centos6 data]#awk 'BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100000);print total}'
5000050000

3、awk中使⽤for迴圈

【例】計算100內整數的和
[root@centos6 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
5050     

4、性能⽐較

【例】分別使⽤awk的while迴圈、shell的for迴圈等計算100000內的整數和,測試執⾏時間  
[root@centos6 ~]# time (awk 'BEGIN{total=0;i=0;do{total+=i;i++;}while(i<=100000);print
total}')
5000050000
real 0m0.013s
user 0m0.012s
sys 0m0.000s
[root@centos6 ~]# time ( sum=0;for i in {1..100000};do let sum+=i;done;echo sum=$sum )
sum=5000050000
real 0m0.727s
user 0m0.570s
sys 0m0.157s
[root@centos6 ~]# time ( seq -s "+" 100000|bc )
5000050000
real 0m0.107s
user 0m0.102s
sys 0m0.002s
[root@centos6 ~]# time(for((i=0;i<=100000;i++));do let total+=i;done;echo $total)
5000050000
real 0m0.959s
user 0m0.928s
sys 0m0.030s  

5、continue語句

【例1】計算100內的奇數和
[root@centos6 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}'
2500 

【例2】計算100內偶數和
[root@centos6 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2!=0)continue;sum+=i}print sum}'
2550  

6、break語句

【例】計算100內的整數和,但遇到整數66就不計算了,退出執⾏
[root@centos6 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}'
2145  

7、next語句

【例】顯⽰uid為偶數⾏的第1欄位和第3欄位  
[root@centos6 ~]# awk -F: '{if($3%2!=0)next;print $1,$3}' awktest.txt
root 0
daemon 2
lp 4
shutdown 6
mail 8
uucp 10

awk的數組

  1. 關聯數組:array[index-expression]
  2. index-expression:
    可使用任意字元串;字元串要使用雙引號括起來
    如果某數組元素事先不存在,在引用時,awk會自動創建此元素,並將其值初始化為空串
    若要判斷數組中是否存在某元素,要使用index in array格式進行遍歷
  3. 若要遍曆數組中的每個元素,要使用for迴圈
  4. for(var in array){for-body}
  5. 註意:var會遍歷array的每個索引

1、awk中數組

【例1】創建⼀個weekdays數組,顯⽰索引為mon的數組的中的值
[root@magedu ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print
weekdays["mon"]}'
Monday  

【例2】使⽤awk中數組去重
[root@magedu ~]# cat abc.txt
a
b
c
aa
bb
cc
a
b
c
[root@magedu ~]# awk '!arr[$0]++' abc.txt
a
b
c
aa
bb
cc  

【例3】去重的思路演⽰
[root@magedu ~]# awk '{!arr[$0]++;print $0,arr[$0]}' abc.txt
a 1
b 1
c 1
aa 1
bb 1
cc 1
a 2
b 2
c 2  

2、在awk中使⽤for迴圈遍曆數組中的每個元素

【例4】在awk中創建weekdays數組,並添加兩個元素
[root@magedu ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesay";for(i in
weekdays) {print weekdays[i]}}'
Monday
Tuesay  

【例5】統計netstat -tan命令結果中各個狀態的數量
⽣成TIME-WAIT連接:
[root@magedu ~]# ab -c 10 -n 200 http://172.16.103.78/
統計各個tcp狀態的個數:
[root@magedu ~]# ss -tan|awk '!/State/{state[$1]++}END{for(i in state){print i,state[i]}}'
ESTAB 1
TIME-WAIT 207
LISTEN 15  

【例6】統計httpd的訪問⽇志中每個ip訪問的次數
[root@magedu ~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
172.18.120.26 261
172.18.116.232 3  

【例7】統計連接本機的ip地址出現的次數
[root@magedu ~]# ss -nt|awk -F '[ :]+' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}'
172.16.101.234 1
或統計訪問次數前⼗的ip地址:
[root@magedu ~]# ss -nt|awk -F '[ :]+' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}' | sort -nr -k2 | head  

【例8】查找連接本機的次數⼤於20的ip地址,加⼊到防⽕牆禁⽌連接
[root@magedu ~]# ss -nt | awk -F'[ :]+' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}' | while read line; do ip=`echo $line | awk '{if($2>20)print $1}'`;[ -z "$ip" ]
|| iptables -A INPUT -s $ip -j REJECT; done
或⽤cut簡單簡單實現:
[root@magedu ~]# ss -nt | awk -F'[ :]' '!/State/{ip[$(NF-2)]++}END{for(i in ip){print
i,ip[i]}}' |while read line; do num=`echo $line | cut -d" " -f2`; ip=`echo $line | cut -d"
" -f1`;[ $num -gt 3 ] && iptables -A INPUT -s $ip -j REJECT; done  

【例9】有⼀個score.txt的⽂件,其內容是學⽣姓名、性別和分數,要求男⽣和⼥⽣的平均分
[root@magedu ~]# cat socre.txt
name sex score
mage m 100
wang m 90
li f 99
zhao f 95
[root@magedu ~]# awk '!/name/{if($2=="m"){m++;msum+=$3};if($2=="f"){f++;fsum+=$3}}END{print
"mavg="msum/m,"favg="fsum/f}' socre.txt
mavg=95 favg=97
或:
[root@magedu ~]# awk '!/name/{num[$2]++;sum[$2]+=$3}END{for(i in num){print i "
avg="sum[i]/num[i]}}' socre.txt
m avg=95
f avg=97  

awk的函數

  1. 數值處理:
    rand():返回0和1之間的一個隨機數,搭配srand()使用
  2. 字元串處理:
    length([s]):返回指定s字元串的長度
    sub(r,s[t]):對t字元串進行搜索r表示的模式匹配的內容,並將第一個匹配的內容替換為s
    gsub(r,s,[t]):對t字元串進行搜索r表示的模式匹配的內容,並全部替換為s所表示的內容
    split(s,array,[r]):以r為分隔符,切割字元串s,並將切割後的結果保存至array所表示的數組中,第一個索
    引值為1,第二個索引值為2,...
  3. ⾃定義函數:
    格式:
    function name (parameter1, parameter2, ...){
    statemenets
    return expression
    }

1、rand()函數:⽣成隨機數

【例1】⽣成⼀個0到1之間的隨機數
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{print rand()}'
0.237788
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.792207
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.046763
[root@magedu ~]# awk 'BEGIN{srand(); print rand()}'
0.046763
或使⽤shell中⽣成隨機數的⽅法:
[root@magedu ~]# echo $RANDOM
8149
[root@magedu ~]# echo $RANDOM
29261
[root@magedu ~]# echo $RANDOM
10121  

【例2】使⽤awk的迴圈,⽣成10個0-1之間的隨機數
[root@magedu ~]# awk 'BEGIN{srand();for(i=0;i<10;i++)print rand()}'
0.90757
0.89926
0.390811
0.546444
0.441346
0.366411
0.17337
0.301543
0.51216
0.883284  

【例3】使⽤awk的迴圈,利⽤int函數⽣成10個整數的隨機數
[root@magedu ~]# awk 'BEGIN{srand();for(i=0;i<10;i++)print int(rand()*100)}'
1
68
10
71
94
19
77
23
18
83  

2、length()函數:統計字元長度

【例4】計算“這是abc”的字元長度
[root@magedu ~]# awk 'BEGIN{print length("這是abc")}'
5  

3、sub()函數:替換第⼀次匹配的字元

【例5】把第⼀個冒號替換成連字元(-)
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk 'sub(/:/,"-",$1)'
2018-08:17 15:47:50

4、gsub()函數:全部替換

【例6】把所有冒號替換成連字元(-)
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk 'gsub(/:/,"-",$0)'
2018-08-17 15-47-50
5、split()函數:指定分隔符,分隔字元串
【例7】以冒號為分隔符,分別顯⽰每個欄位
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[1]}'
2018
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[2]}'
08
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[3]}'
17 15
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[4]}'
47
[root@magedu ~]# echo "2018:08:17 15:47:50" |awk '{split($0,array,":");print array[5]}'
50
【例8】統計連接本機為建⽴狀態的ip地址的數量
[root@magedu ~]# netstat -tn|awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in
count){print i,count[i]}}'
172.16.101.234 1   

6、⾃定義函數

【例9】獲得兩參數的最⼤值,⾃定義函數,在函數內部參數固定
[root@magedu ~]# cat awk.fn
function max(v1,v2){
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
[root@magedu ~]# awk -f awk.fn
3
【例10】獲得兩參數的最⼤值,根據上例,把參數改為可變動的
[root@magedu ~]# cat awk.fn
function max(v1,v2){
v1>v2?var=v1:var=v2
return var
}
BEGIN{print max(a,b)}
[root@magedu ~]# awk -v a=10 -v b=30 -f awk.fn
30

awk調⽤系統命令和其他功能

  1. system命令;
    空格是awk中的字元串連接符,如果system中需要使用awk中的變數可以使用空格分隔,或者說除了awk的變數外其
    他一律用""引用起來。
  2. awk的其他功能:
    將awk程式寫成腳本,直接調用或執行
  3. 向awk腳本傳遞參數
    格式:awkfile var1=value1 var2=value2 ... Inputfile
  • 註意:在BEGIN過程中不可使⽤,直到⾸⾏輸⼊完成以後,變數才可⽤;可通過-v參數,讓awk在執⾏BEGIN之前得到變
    量的值;命令⾏中每⼀個指定的變數都需要⼀個-v參數。

1、使⽤system()函數調⽤linux命令

【例1】在awk中調⽤linux系統的hostname命令
[root@magedu ~]# hostname
magedu
[root@magedu ~]# awk 'BEGIN{system("hostname")}'
magedu
【例2】在awk中使⽤linux中echo命令顯⽰awk中的變數
[root@magedu ~]# awk 'BEGIN{score=100;system("echo you score is "score)}'
you score is 100
【例3】在awk中使⽤iptables命令拒絕來源地址為1.1.1.1的訪問
[root@magedu ~]# awk 'BEGIN{ip="1.1.1.1";system("iptables -A INPUT -s " ip " -j REJECT")}'  

2、awk腳本

【例4】編寫awk腳本,顯⽰/etc/passwd中,uid⼤於500的⽤戶和uid
[root@magedu ~]# cat f1.awk
#!/bin/awk -f
{if($3>=500)print $1,$3}
[root@magedu ~]# chmod +x f1.awk
[root@magedu ~]# ./f1.awk -F: /etc/passwd
nfsnobody 65534
llj 500
li 501
zhang 502
python 503  

5、給awk腳本傳遞參數

【例5】顯⽰/etc/passwd⽂件中,uid在10-20之間的⽤戶名和uid
[root@magedu ~]# cat f2.awk
#!/bin/awk -f
{if($3>=min && $3<=max)print $1,$3}
[root@magedu ~]# chmod +x f2.awk
[root@magedu ~]# ./f2.awk -F: min=10 max=20 /etc/passwd
uucp 10
operator 11
games 12
gopher 13
ftp 14
或使⽤-v參數指定:
[root@magedu ~]# ./f2.awk -F: -v min=10 -v max=20 /etc/passwd  

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

-Advertisement-
Play Games
更多相關文章
  • 鴿了好久,終於有個時間繼續寫了,繼上一篇之後,又寫(水)了一篇,有什麼不足之處請大家指出,多謝各位了。 下麵有兩個需要用到的軟體,putty和pscp,我已經上傳到博客園了,下載請點擊這裡。 一、準備伺服器 首先和之前一樣,先去騰訊雲整了個雲伺服器,選擇CentOS的鏡像。 然後跟之前一樣完成購買, ...
  • 1.阻止from提交:在按鈕的click事件中加入$("#btnSubmit").attr("disabled", "disabled");; 2.使用ajaxfrom提交不刷新頁面 必須要引<script src="~/Scripts/jquery.validate.min.js"></scrip ...
  • 總結下麵幾點 1.與下位機的連接儘量保持長連接,每次用到的時候去連接的話,過一段時間速度明顯下降,什麼問題並沒有找到 2.C#中的BitConverter 類可以非常方便的在位元組與其他類型之間進行轉換 3.周期性操作使用while迴圈,避免使用timer定時器 4.操作一些標誌位的操作,儘量放到一個 ...
  • VS2017打開項目時提示未能正確載入CSharpPackage包, 可以使用 devenv命令工具來解決,操作如下 打開vs2017開發人員命令提示符(請使用管理員身份運行),如圖 敲入 devenv /setup 回車執行 最後重啟vs解決。 有的再重啟vs時還會出現 未能正確載入“Micros ...
  • KindEditor使用JavaScript編寫,可以無縫的於Java、.NET、PHP、ASP等程式接合。 KindEditor非常適合在CMS、商城、論壇、博客、Wiki、電子郵件等互聯網應用上使用,2006年7月首次發佈2.0以來,KindEditor依靠出色的用戶體驗和領先的技術不斷擴大編輯 ...
  • 一、簡介 方法可以稱為函數,函數又可以稱為方法,方法主要的作用是將一堆代碼進行重用的一種機制,避免太多的冗餘的代碼,還有方便後期維護。 二、語法 函數的語法: 描述: public:訪問修飾符,公開的; static:靜態的; 返回值類型:比如int 、string 、double等的類型,如果不寫 ...
  • 上一篇隨筆記錄到RabbitMQ的安裝,安裝完成,我們就開始使用吧。 RabbitMQ簡介 AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標準,為面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息 ...
  • Ubuntu下經常遇到無法用快捷鍵關閉觸控板的情況,博主的電腦安裝Ubuntu18.04後便出現了該問題。 解決辦法: 首先查看輸入設備的id,命令行輸入: xinput ,如圖,博主的TouchPad的id=17,電腦不同id各異, 知道了id=17之後,就可以通過命令關閉/開啟觸控板, 關閉命令 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...