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

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

1. awk概述

1.1 awk是什么

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

1.2 為什么用awk

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

2. awk的適用場(chǎng)景

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

3. awk的處理模式

一般是遍歷一個(gè)文件中的每一行,然后分別對(duì)文件的每一行進(jìn)行處理。

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

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

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

總體可以分為以下三步:

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

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

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

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

4.1 語(yǔ)法

Awk 語(yǔ)法格式如下圖所示:

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

awk 的語(yǔ)法格式主要分為四個(gè)字段,options 選項(xiàng),引號(hào)內(nèi)有模塊與動(dòng)作,以及要處理的文件,接下來(lái)讓我們?cè)敿?xì)講解每一個(gè)語(yǔ)法字段,更全面地認(rèn)識(shí) awk 這個(gè)腳本利器。

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

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

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

4.3 awk命令詳解

4.3.1 awk 輸出

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

1.各字段之間逗號(hào)隔開(kāi),輸出時(shí)以空白字符分隔;

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

3.print 命令后面的 item 可以省略,此時(shí)其功能相當(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...

要點(diǎn):

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

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

3.printf 語(yǔ)句不會(huì)自動(dòng)打印換行字符\n。

format 格式的指示符都以 % 開(kāi)頭,后跟一個(gè)字符:

%c:顯示ascall碼
%d:%i:十進(jìn)制整數(shù)
%e%E:科學(xué)計(jì)數(shù)法
%f:浮點(diǎn)數(shù)
%s:字符串
%u:無(wú)符號(hào)整數(shù)
%%:顯示%自身

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

%3.1f

-:左對(duì)齊
+:顯示數(shù)組符號(hào)

例如:

[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)回車(chē))
    • ORS:輸出文本換行符
  • 數(shù)據(jù)變量

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

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

    • FILENAME:awk 命令處理的文件名稱(chēng)

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

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

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

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

4.3.3 操作符

  • 算術(shù)運(yùn)算

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

    • 無(wú)符號(hào)操作符,表示字符串連接,例如:
    [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)
  • 條件表達(dá)式(三元運(yùn)算):

    • 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)系表達(dá)式,結(jié)果為“真”有“假”,結(jié)果為“真”才會(huì)被處理。

Tips:使用模式需要使用雙斜線(xiàn)括起來(lái),真:結(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{}:僅在開(kāi)始處理文本之前執(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 控制語(yǔ)句

  • 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. 實(shí)例

1.統(tǒng)計(jì)/etc/fstab文件中每個(gè)單詞出現(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)計(jì)/etc/fstab每個(gè)文件系統(tǒng)類(lèi)型出現(xiàn)的次數(shù)
awk '!/^#/&&!/^$/{dev[$3]++}END{for(i in dev) print i,dev[i]}' /etc/fstab

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

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

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

6. 注意事項(xiàng)

  • awksed命令類(lèi)似,只不過(guò)sed擅長(zhǎng)取行,awk命令擅長(zhǎng)取列,awk是對(duì)文本進(jìn)行格式化輸出,sed更傾向于對(duì)文件進(jìn)行修改;

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

  • awk非常的強(qiáng)大,但是也是三劍客中最難的一個(gè),其作為一門(mén)單獨(dú)的語(yǔ)言,我們?cè)赟hell編程中學(xué)習(xí)常用的命令及語(yǔ)法就已經(jīng)足夠我們使用。

7. 小結(jié)

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