第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Shell三劍客之a(chǎn)wk

1. awk概述

1.1 awk是什么

awk不同于grep的文本搜索與sed工具的文本處理,它更偏向于對文本的格式化處理輸出,它不僅僅是一款工具,也是一門解釋性語言,其名字來源于它的三位作者的姓氏:Alfred Aho, Peter WeinbergerBrian Kernighan,在文本處理功能非常強大,是一款Linux服務(wù)器文本報告生成器和格式化文本輸出工具。

1.2 為什么用awk

我們?nèi)粘9ぷ髦杏泻芏嘈枰袷交蛴≥敵龅男枨螅嗟氖顷P(guān)注列操作時,就可以利用awk工具來進行處理。awk除了是工具也同樣是一門語言,其允許用戶創(chuàng)建簡短的程序來處理自己的需求,這些程序讀取輸入文件、為數(shù)據(jù)排序、處理數(shù)據(jù)、對輸入執(zhí)行計算以及生成報表等。功能非常的強大,相信在掌握了awk,日常運維工作更加方便高效簡單。

2. awk的適用場景

  • 超大文件處理;
  • 輸出格式化的文本報表;
  • 執(zhí)行算數(shù)運算;
  • 執(zhí)行字符串操作等。

3. awk的處理模式

一般是遍歷一個文件中的每一行,然后分別對文件的每一行進行處理。

awk對輸入的一行數(shù)據(jù)進行處理的模式,對整個文件進行重復(fù)執(zhí)行此模式處理,在此說明對輸入的一行數(shù)據(jù)處理的內(nèi)在機制如下圖所示:

處理過程不斷重復(fù),直到到達文件結(jié)尾。

  1. 首先讀入文件流的一行到模式空間;
  2. 在模式空間內(nèi),對內(nèi)容進行模式匹配處理;
  3. 然后輸出處理后的數(shù)據(jù)內(nèi)容;
  4. 清空當(dāng)前模式空間;
  5. 讀取第二行輸入流到模式空間;
  6. 又開始對模式空間內(nèi)的第二行輸入數(shù)據(jù)進行處理。

總體可以分為以下三步:

  • 讀(Read):AWK 從輸入流(文件、管道或者標(biāo)準(zhǔn)輸入)中讀入一行然后將其存入內(nèi)存中。

  • 執(zhí)行(Execute):對于每一行輸入,所有的 AWK 命令按順序執(zhí)行。 默認(rèn)情況下,AWK 命令是針對于每一行輸入,但是我們可以將其限制在指定的模式中。

  • 重復(fù)(Repeate):一直重復(fù)上述兩個過程直到文件結(jié)束。

4. 語法及結(jié)構(gòu)

4.1 語法

Awk 語法格式如下圖所示:

awk [options] 'PATTERN {action}' file1,file2

awk 的語法格式主要分為四個字段,options 選項,引號內(nèi)有模塊與動作,以及要處理的文件,接下來讓我們詳細講解每一個語法字段,更全面地認(rèn)識 awk 這個腳本利器。

4.2 程序結(jié)構(gòu)

awk 在引號內(nèi)有一定的程序結(jié)構(gòu),主要為以下:

  • 開始塊(BEGIN BLOCK):
語法:
BEGIN{awk-commands}
開始塊就是awk程序啟動時執(zhí)行的代碼部分(在處理輸入流之前執(zhí)行),并且在整個過程中只執(zhí)行一次;
一般情況下,我們在開始塊中初始化一些變量。BEGIN是awk的關(guān)鍵字,因此必須要大寫。【注:開始塊部分是可選,即你的awk程序可以沒有開始塊部分】
  • 主體塊(Body Block):
語法:
/pattern/{awk-commands}
針對每一個輸入的行都會執(zhí)行一次主體部分的命令,默認(rèn)情況下,對于輸入的每一行,awk都會執(zhí)行主體部分的命令,但是我們可以使用/pattern/限制其在指定模式下。
  • 結(jié)束塊(END BLOCK):
語法:
END{awk-commands}
結(jié)束塊是awk程序結(jié)束時執(zhí)行的代碼(在處理完輸入流之后執(zhí)行),END也是awk的關(guān)鍵字,必須大寫,與開始塊類似,結(jié)束塊也是可選的。

4.3 awk命令詳解

4.3.1 awk 輸出

  • awk print輸出,例如:
print item1,item2...

1.各字段之間逗號隔開,輸出時以空白字符分隔;

2.輸出的字段可以為字符串或數(shù)值,當(dāng)前記錄的字段(如$1)、變量或 awk 的表達式;數(shù)值先會轉(zhuǎn)換成字符串然后輸出;

3.print 命令后面的 item 可以省略,此時其功能相當(dāng)于print $0,如果想輸出空白,可以使用print "";

例如:

[root@master ~]# awk -F: '{print $1,$NF}' /etc/passwd|column -t
root             /bin/bash
bin              /sbin/nologin
daemon           /sbin/nologin
adm              /sbin/nologin
lp               /sbin/nologin
sync             /bin/sync
  • awk printf 輸出

printf 命令的使用格式:

printf <format> item1,item2...

要點:

1.其與 print 命令最大區(qū)別,printf 需要指定 format,format 必須給出;

2.format 用于指定后面的每個 item 輸出格式;

3.printf 語句不會自動打印換行字符\n。

format 格式的指示符都以 % 開頭,后跟一個字符:

%c:顯示ascall碼
%d:%i:十進制整數(shù)
%e,%E:科學(xué)計數(shù)法
%f:浮點數(shù)
%s:字符串
%u:無符號整數(shù)
%%:顯示%自身

修飾符:
#[.#]:第一個#控制顯示的寬度:第二個#表示小數(shù)點后的精度:

%3.1f

-:左對齊
+:顯示數(shù)組符號

例如:

[root@master ~]# awk -F: '{printf "Username:%-15s   ,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

4.3.2 awk變量

  • 記錄變量:

    • IFS(input field separator),輸入字段分隔符(默認(rèn)空白)
    • OFS(output field separator),輸出字段分隔符
    • RS(Record separator):輸入文本換行符(默認(rèn)回車)
    • ORS:輸出文本換行符
  • 數(shù)據(jù)變量

    • NR:the number of input records,awk 命令所處理的文件的行數(shù),如果有多個文件,這個數(shù)目會將處理的多個文件計數(shù)
    • NF:number of field,當(dāng)前記錄的 field 個數(shù)
    {print NF},{print $NF}
    
    • ARGV:數(shù)組,保存命令行本身這個字符串

    • ARGC:awk 命令的參數(shù)個數(shù)

    • FILENAME:awk 命令處理的文件名稱

    • ENVIRON:當(dāng)前 shell 環(huán)境變量及其值的關(guān)聯(lián)數(shù)組

    awk 'BEGIN{print ENVIRON["PATH"]}'
    
  • 自定義變量
    -v var=value

    變量名區(qū)分大小寫,例如:

    [root@master ~]#  awk -v test="abc" 'BEGIN{print test}'
    abc
    [root@master ~]# awk 'BEGIN{var="name";print var}'
    name
    

4.3.3 操作符

  • 算術(shù)運算

    • +,-,*,/,^,%。例如:
    [root@master ~]# awk 'BEGIN{a=5;b=3;print "a + b =",a+b}'
    a + b = 8
    
  • 字符串操作

    • 無符號操作符,表示字符串連接,例如:
    [root@master ~]# awk 'BEGIN { str1="Hello,"; str2="World"; str3 = str1 str2; print str3 }'
    Hello,World
    
  • 賦值操作符:

    • =,+=,-=,*=,/=,%=,^=,例如:
    [root@master ~]# awk 'BEGIN{a=5;b=6;if(a == b) print "a == b";else print "a!=b"}' 
    a!=b
    
    [root@master ~]# awk -F: '{sum+=$3}END{print sum}' /etc/passwd
    72349
    
  • 比較操作符:

    • >,>=,<,<=,!=,==
  • 模式匹配符:

    • ~:是否匹配
    • !~:是否不匹配

    例如:

    [root@master ~]# awk -F: '$1~"root"{print $0}' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    
  • 邏輯操作符:

    • && 、 || 、 !,例如:
    [root@master ~]# awk 'BEGIN{a=6;if(a > 0 && a <= 6) print "true";else print "false"}'
    true
    
  • 函數(shù)調(diào)用:

    • function_name(argu1,augu2)
  • 條件表達式(三元運算):

    • selection?if-true-expresssion:if-false-expression
    [root@master ~]# awk -F: '{$3>=100?usertype="common user":usertype="sysadmin";printf "%15s:%s\n",$1,usertype}' /etc/passwd
               root:sysadmin
                bin:sysadmin
             daemon:sysadmin
                adm:sysadmin
                 lp:sysadmin
               sync:sysadmin
           shutdown:sysadmin
               halt:sysadmin
    

4.3.4 Pattern

  • empty:空模式,匹配每一行
  • /regular expression/:僅處理能被此處模式匹配到的行,例如;
[root@master ~]# awk -F: '$NF=="/bin/bash"{printf "%15s,%s\n",$NF,$1}' /etc/passwd
      /bin/bash,root
  • relational expression:關(guān)系表達式,結(jié)果為“真”有“假”,結(jié)果為“真”才會被處理。

Tips:使用模式需要使用雙斜線括起來,真:結(jié)果為非0值,非空字符串。

[root@master ~]# awk -F: '$3>100{print $1,$3}' /etc/passwd
systemd-network 192
polkitd 999
ceph 167
kube 998
etcd 997
gluster 996
nfsnobody 65534
chrony 995
redis 994
awk -F: '$NF=="/bin/bash"{printf "%15s,%s\n",$NF,$1}' /etc/passwd
awk -F: '$NF~/bash$/{printf "%15s,%s\n",$NF,$1}' /etc/passwd
df -Th|awk '/^\/dev/{print}'
  • line ranges:行范圍,制定startline,endline。

    [root@master ~]# awk -F: '/10/,/20/{print $1}' /etc/passwd
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd
    postfix
    sshd
    ceph
    kube
    etcd
    gluster
    rpc
    
  • BEGIN/END模式

    • BEGIN{}:僅在開始處理文本之前執(zhí)行一次
    • END{}:僅在文本處理完成之后執(zhí)行一次
    [root@master ~]# awk -F: 'BEGIN{print "username     uid\n--------------------"}{printf "%-15s:%d\n",$1,$3}END{print "-----------------\nend"}' /etc/passwd
username     uid
    --------------------
    root           :0
    bin            :1
    daemon         :2
    adm            :3
    lp             :4
    rpc            :32
    rpcuser        :29
    nfsnobody      :65534
    chrony         :995
    redis          :994
    -----------------
    end

4.3.5 控制語句

  • if(condition) {statements},例如:
[root@master ~]# awk -F: '{if($3>100) print $1,$3}' /etc/passwd
systemd-network 192
polkitd 999
ceph 167
kube 998
etcd 997
gluster 996
nfsnobody 65534
chrony 995
redis 994
  • if(condition) {statments} [else {statments}],例如:
[root@master ~]# awk -F: '{if($3>100) {printf "Common user:%-15s\n",$1} else {printf "sysadmin user:%-15s\n",$1}}' /etc/passwd
sysadmin user:root           
sysadmin user:bin            
sysadmin user:daemon         
sysadmin user:adm            
sysadmin user:lp             
sysadmin user:sync           
sysadmin user:shutdown       
sysadmin user:halt           
sysadmin user:mail           
sysadmin user:operator       
sysadmin user:games          

5. 實例

1.統(tǒng)計/etc/fstab文件中每個單詞出現(xiàn)的次數(shù),并按從大到小排序
awk '{for(i=1;i<=NF;i++){words[$i]++}}END{for(key in words)print key,words[key]}' /etc/fstab|sort -k2 -nr

awk '{ips[$1]++}END{for(i in ips) print i,ips[i]}' access_nginx.log |column -t|sort -k2 -nr

2.統(tǒng)計/etc/fstab每個文件系統(tǒng)類型出現(xiàn)的次數(shù)
awk '!/^#/&&!/^$/{dev[$3]++}END{for(i in dev) print i,dev[i]}' /etc/fstab

3.ping一個域名,輸出ping此刻的時間
ping baidu.com|awk '{print $0" "strftime("%Y-%m-%d %H:%M:%S")}'

4.利用netstat監(jiān)控服務(wù)是否正常監(jiān)聽
netstat -lntup|awk 'NR>2{if($4 ~/.*:22/) print $0"yes";exit 0}'

5.統(tǒng)計web服務(wù)器日志狀態(tài)碼
awk '$9~"[0-9]"{stat[$9]++}END{for(i in stat) print i,stat[i]}' access_log

6. 注意事項

  • awksed命令類似,只不過sed擅長取行,awk命令擅長取列,awk是對文本進行格式化輸出,sed更傾向于對文件進行修改;

  • 對于讀入的文件可以根據(jù)自己需求對IFS/OFS對輸入和輸出進行修改;

  • awk非常的強大,但是也是三劍客中最難的一個,其作為一門單獨的語言,我們在Shell編程中學(xué)習(xí)常用的命令及語法就已經(jīng)足夠我們使用。

7. 小結(jié)

本章節(jié)我們系統(tǒng)性地學(xué)習(xí)了awk的語法結(jié)構(gòu)及處理模式,其相較于其他文本處理工具,更適合對文本進行格式化輸出,我們需要在合適的地方使用,其作為Linux系統(tǒng)上一個非常強大的文本格式輸出工具,也是一門語言,后期需要在實踐工作中更多地靈活運用,使得腳本編寫更加方便。