awk快速入门
AWK快速入門
awk簡介
awk是一個優(yōu)良的文本處理工具,是Linux中文本三劍客之一,awk的名字取自于其創(chuàng)始人Alfred Aho、Peter Weinberger和Brain Kernighan三人姓式的首字母。
awk的功能及其強(qiáng)大,可以進(jìn)行式樣裝入、流控制、數(shù)學(xué)運(yùn)算符、進(jìn)程控制語句甚至內(nèi)置的變量和函數(shù),他具備了一個完整語言所應(yīng)有的幾乎所有特性。
awk語法
awk程序由BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成
awk [option] '[BEGIN{action;...}]pattern{action;...}[END{action;...}]' file| -F | 指定分隔符 |
| -f | 指定awk程序文件 |
| -v | 變量賦值,每個變量都需要使用-v var=value來賦值 |
awk工作原理
1.執(zhí)行BEGIN{action;...}語句塊中的語句
BEGIN語句塊在awk開始從輸入流中讀取的行之前被執(zhí)行,這是個可選的語句塊,
2.從文件或標(biāo)準(zhǔn)輸入中讀取一行,然后執(zhí)行pattern{action;...}語句塊,它逐行掃描文件,從第一行到最后一行重復(fù)這個過程,直到文件全部被讀取完畢。
3。當(dāng)讀至輸入流末尾時,執(zhí)行END{action;...}語句塊。
END語句塊,在awk從輸入流種讀取完所有的行之后再執(zhí)行,比如打印所有行的分析結(jié)果這里信息匯總都是在END語句中完成,它也是個可選語句塊
awk基本用法
awk最簡單的使用方法為:
awk [option] 'pattern{action;...}' file一、print
print的參數(shù)可以是變量、數(shù)值或字符串。字符串必須用雙引號引用,參數(shù)用逗號分隔。如果沒有逗號,參數(shù)就串聯(lián)在一起,無法區(qū)分。這里逗號的作用與輸出文件的分隔符所用是一樣的,只是后者是空格而已。當(dāng)pattern不指定時默認(rèn)打印文件中所有的行。
示例1:打印/etc/fstab中的每一行
二、awk變量
awk有內(nèi)置變量和自定義變量
內(nèi)置變量有FS、OFS、RS、ORS、NF、FNR、FILENAME、ARGC、ARGV
1.FS:設(shè)置輸入域分隔符,等價于命令行選項(xiàng)-F
示例1:使用變量FS指定分隔符,取出/etc/fstab的第1第3列
[root@centos7 ~]# awk -v FS=: '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...示例2:使用選項(xiàng)-F指定分隔符,取出/etc/fstab的第1第3列
[root@centos7 ~]# awk -F":" '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...示例3:用正則表達(dá)式當(dāng)分隔符取出分區(qū)利用率
[root@centos7 ~]# df | awk -F"[[:space:]]+|%" '{print $5}' Use 15 0 0 2 0 1 17示例4:變量在action中也能被引用,在第一個域和第3個域之間加:號
[root@centos7 ~]# awk -v FS=: '{print $1,FS,$3}' /etc/passwd root : 0 bin : 1 daemon : 2 ...以下省略...2.OFS:設(shè)置輸出時域分隔符,默認(rèn)為空白
示例1:以:為分隔符分隔字段,輸出時以+++為分隔符,取出/etc/passwd第1第2字段
[root@centos7 ~]# awk -v FS=: -v OFS=+++ '{print $1,$2}' /etc/passwd root+++x bin+++x daemon+++x ...以下省略...3.RS:設(shè)置記錄分隔符
當(dāng)記錄的分割符指定為某符號時,從字符開始至記錄分隔符的字符串為一條記錄,記錄的條數(shù)和行數(shù)無關(guān)。
示例1:創(chuàng)建一個文本指定;為分隔符查看記錄情況。
以上面文件內(nèi)容為例,以分號為記錄的分隔符,此文件一共有5條記錄。
[root@centos7 ~]# awk -v RS=";" '{print $0}' a.txt a,b,c 1,2,3,4, aa,bb,cc #此行與下一行為一條記錄中間隱藏了一個換行符 zz,yy,xxx 122,444,2322 AA #此行與下一行為一條記錄中間隱藏了一個換行符 BB,CC4.ORS:設(shè)置輸出時記錄分隔符
ORS變量指定輸出時的記錄分隔符為什么符號。
示例:
依舊為a.txt文件,設(shè)置分隔符為,號,紀(jì)錄分隔符為;號,輸出時設(shè)置記錄分分隔符為___,取出第一字段。
5.NF:域數(shù)
NF可以查看一條記錄內(nèi)有多少個域,也可以用來查看倒數(shù)第N個字符為什么
示例1:
以/etc/passwd為例,以:號為分隔符查看每行的字段數(shù)量
示例2:
差看/etc/passwd文件內(nèi),以:為分隔符,倒數(shù)第2個字段的內(nèi)容
6.NR:記錄數(shù)
NR變量為已讀文件的記錄數(shù)
示例1:
以;為記錄符,在a.txt的文件的每條記錄前加上記錄行。
NR變量還可以合并計(jì)數(shù)多個文件的記錄
示例2:查看/etc/fstab和/etc/issue總共有多少記錄號
7.FNR:文件的記錄數(shù)
FNR變量為每個文件分別記錄記錄數(shù)。
示例:查看/etc/fstab和/etc/issue的記錄數(shù)
8.FILENAME:文件名
FILENAME變量為輸出文件名
示例:在匹配到的行后面加上文件名
9.ARGC:命令行參數(shù)個數(shù)
ARGC變量存放的為參數(shù)個數(shù)。
示例:
顯示為2個參數(shù),是哪兩個參數(shù)呢?看下面那個函數(shù)
10.ARGV:查看命令行參數(shù)
ARGV變量為一個數(shù)組里面存放的為awk的每個參數(shù)
示例:
打印每一個參數(shù)
自定義變量
自定義變量的賦值有2種方法
1.-v var=value
示例1:輸出變量在每行
[root@centos7 ~]# awk -v title=ceo -F: '{print title":"$1}' /etc/passwd ceo:root ceo:bin ceo:daemon ceo:adm ceo:lp2.可以直接在program中直接定義
把變量賦值放在{}內(nèi),把變量放在{}內(nèi)賦值時變量值必須要加雙引號,變量必須先賦值再引用,次序錯誤會導(dǎo)致第一次匹配到的行沒有值
示例1:在每個用戶前加上ceo
示例2:調(diào)用腳本文件
awk '{action}' 單引號內(nèi)的腳本可以存放在文件內(nèi)被調(diào)用
三、printf
printf格式化輸出:
printf "FORMAT" ,item1,item2,...| %c | 顯示字符的ASCII碼 |
| %d,%i | 顯示十進(jìn)制整數(shù) |
| %e,%E | 顯示科學(xué)計(jì)數(shù)法數(shù)值 |
| %f | 顯示浮點(diǎn)數(shù) |
| %g | 以科學(xué)計(jì)數(shù)法或浮點(diǎn)形式顯示數(shù)值 |
| %s | 顯示字符串 |
| %u | 無符號整數(shù) |
| %% | 顯示%自身 |
| #[.#] | 第一個數(shù)字控制顯示的寬度;第二個#標(biāo)識小數(shù)點(diǎn)后精度,%3.1f |
| - | 左對齊(默認(rèn)為右對齊)%-15s |
| + | 顯示數(shù)值的正負(fù)值符號%+d |
示例1:
%d打印整數(shù)
示例2:
格式符有幾個對應(yīng)的item項(xiàng)就要就幾個否則語法錯誤
示例3:
%f可以打印小數(shù),默認(rèn)輸出的為6位。也可以指定小數(shù)位。
示例4:
.之前的數(shù)字為長度(默認(rèn)右對齊)
示例5:
指定左對齊,在%后面加上-
四、操作符
awk還支持各種操作符如算數(shù)操作符、字符串操作符、賦值操作符、比較操作符、模式匹配操作符
1.算數(shù)操作符
算數(shù)操作符有+、-、、/、^、%,如:
x+y,x-y,xy,x/y,x^y,x%y
示例1:
簡單的算術(shù)運(yùn)算
示例2:
-x:轉(zhuǎn)換為負(fù)數(shù)
2.賦值操作符:
賦值操作符有:=,+=,-=,*=,/=,%=,^=,++,--
示例1:
3.比較操作符和模式匹配符
比較操作符和模式匹配符常用在awk的行過濾pattern中,Pattern為空時所有都符合條件
pattern中可以添加比較符號和模式匹配
比較符號有:==(等于),!=(不等于),>(大于),>=(大于等于),<(小于),<=(小于等于)
模式匹配符:~(符號左邊內(nèi)容是否右邊匹配內(nèi)容,包含內(nèi)容),!~(符號左邊內(nèi)容的是否不匹配右邊內(nèi)容)
模式匹配時可以使用正則表達(dá)式!
3.1比較操作符示例
示例1:
取出連接主機(jī)的IP
示例2:
取出用戶列表中UID大于1000的用戶和ID
示例3:
取出ip地址
示例4:
取出分區(qū)利用率大于10的設(shè)備
3.2模式匹配示例
示例1:匹配第一列為/dev/sd開頭行
示例2:匹配/etc/fstab非#開頭的行
[root@centos7 ~]# awk '!/^#/' /etc/fstab UUID=45490aa4-cf29-420d-a606-af32688b6707 / xfs defaults 0 0 UUID=15dcd896-b7cf-48d0-b8bd-4c0b0f2c62b2 /boot xfs defaults 0 0 UUID=4b6e1813-2c46-402a-869a-02cbbcb76ade /data xfs defaults 0 0 UUID=0995b444-48c1-4423-92bc-2deda0d3c082 swap swap defaults 0 04.邏輯操作符
邏輯操作符:與&&,或||,非!
示例1:
取出/etc/passwd非nologin結(jié)尾的行
示例2:
取出分區(qū)利用率大于10的設(shè)備名和分區(qū)利用率
示例3:
取出連接數(shù)前3的IP地址
5.三目表達(dá)式
三目表達(dá)式格式:
selector?if-ture-expression:if-false-expression
判斷selector是否為真,如果為真則執(zhí)行if-ture語句,不為真則執(zhí)行if-false語句。
示例1:
在Uid大于等于1000的用戶前添加commom user,小于1000的添加system user
五、PATTERN部分總結(jié)
PATTEN:awk在執(zhí)行時會根據(jù)pattern條件,過濾匹配的行,再做處理。
pattern的條件可以有以下幾種:
1.空
如果pattern部分為空,則默認(rèn)匹配每一行
示例:打印所有行
2.正則表達(dá)式
/regular expression/:僅處理能夠被模式匹配到的行,需要用//括起來
示例:找出/etc/passwd中以g開頭的行的第1字段和第3字段
3.關(guān)系表達(dá)式
relational expression: 關(guān)系表達(dá)式,結(jié)果為“真”才會被處理
真和假的定義:
3.1真:結(jié)果為非0值,非空字符串
示例1: 當(dāng)有值時為真,輸出所有。
示例2:當(dāng)數(shù)字為負(fù)數(shù)時,輸出也為真
[root@centos7 ~]# seq 3 | awk '"-1"' 1 2 3示例3:當(dāng)中間的數(shù)字為空格時也為真
[root@centos7 ~]# seq 3 | awk '" "' 1 2 33.2假:結(jié)果為空字符串或0值,假則不會被處理
示例1:當(dāng)值為空和0時不做輸出
示例2:在awk中不加字符不添加雙引號表示為變量,變量為空和0時也為假,變量中有值時為真
[root@centos7 ~]# seq 5 | awk 'i' #變量中沒有值,假 [root@centos7 ~]# seq 5 | awk -v i=1 'i' #變量中有值,真,輸出結(jié)果 1 2 3 4 54.行范圍
pattern可以使用行范圍進(jìn)行匹配
/pat1/,/pat2/ 不支持直接給出數(shù)字格式
示例:打印b開頭的行到f開頭的行
5.BEGIN/END模式
BEGIN{}:僅在開始處理文件中的文本之前執(zhí)行一次
END{}:僅在文本處理完成之后執(zhí)行一
示例1:使用BEGIN來添加表頭,做格式化輸出。
六、awk控制語句
流程控制語句是任何程序設(shè)計(jì)語言都不能缺少的部分。任何好的語言都有一些執(zhí)行流程控制的語句。awk提供的完備的流程控制語句類似于C語言,這給我們編程帶來了極大的方便。
awk控制語句有:if-else,while循環(huán),do-while循環(huán),for循環(huán),break,continue,delete array[index],delete array,exit
1.if-else
使用場景:對awk取得的整行或某個字段做條件判斷
語法:
示例:1.打印出/etc/passwd下uid大于1000的行
[root@centos7 ~]# awk -F: '{if($3>1000)print $0}' /etc/passwd nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin示例2:如果Uid為偶數(shù)則打印出uid和用戶名
[root@centos7 ~]# awk -F: '{if($3%2==0)print $1,$3}' /etc/passwd root 0 daemon 2 lp 4 shutdown 6 mail 8 games 12 ftp 14 systemd-network 192 libstoragemgmt 998 rpc 32 saslauth 996 rtkit 172 nfsnobody 65534 unbound 994 geoclue 992 saned 990 gdm 42 sshd 74 avahi 70 ntp 38 tcpdump 72 masuri 1000示例3:考試成績判斷,60及格,80分還行,80分以上真棒,60以下不及格
[root@centos7 ~]# awk -v score=80 'BEGIN{if(score<60){print "no pass"}else if(score<=80){print "just so so"}else if(score>80){print "good"}}' just so so2.while循環(huán)
使用場景:
1.對一行內(nèi)的多個字段逐一類似處理時使用
2.對數(shù)組中的各元素逐一處理時使用
語法:
條件為真進(jìn)入循環(huán),條件為假退出循環(huán)。
示例1:打印/etc/password第一行每一字段的長度
示例2:取出最大值和最小值
[root@centos7 ~]# awk -F, '{max=$1;mix=$1;i=1;while(i<=NF){if($i>max){max=$i};if($i<mix){mix=$i};i++};print mix,max}' test1 207 31976示例3:1+2+3+..+100
[root@centos7 ~]# awk 'BEGIN{i=1;while(i<=100){sum+=i;i++}print sum}' 50503.for循環(huán)
常用語法:
for(expr1;expr2;expr3){statement;...}特殊用法:便利數(shù)組中的元素
語法:
示例1:for循環(huán)1+到100
[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum+=i}print sum}' 50504.break和continue
break為提前結(jié)束循環(huán)
continue為提前結(jié)束本次循環(huán),進(jìn)入下一次循環(huán)
示例:將1到100的偶數(shù)相加
1-100的偶數(shù)相加,當(dāng)i=50時跳出不加,繼續(xù)執(zhí)行后續(xù)循環(huán)
[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50){continue};if(i%2==0){sum+=i}}print sum}' 25001-100的偶數(shù)相加,當(dāng)i=50時跳出所有循環(huán)
[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50){break};if(i%2==0){sum+=i}}print sum}' 6005.next
next是提前結(jié)束對本行的處理直接進(jìn)入下一行的處理,next跳出的是awk自身的循環(huán)。
示例:
打印Uid為偶數(shù)的行
七、awk數(shù)組
awk數(shù)組為關(guān)聯(lián)數(shù)組:array[index-expression]
index-expression為數(shù)組下標(biāo)
數(shù)組在使用時需注意以下幾點(diǎn):
1.數(shù)組下標(biāo)可使用任意字符串;字符串要使用雙引號括起來
2.如果某數(shù)組元素事先不存在,在引用時,awk會自動創(chuàng)建此元素,并將其初始化為“空串”
3.若要判斷數(shù)組中是否存在某元素,要時用“index in array”格式進(jìn)行遍歷
示例:給數(shù)組賦值,和輸出數(shù)組
[root@centos7 ~]# awk 'BEGIN{arr["ceo"]="mage";arr["cto"]="laowang";print arr["ceo"]}' mage [root@centos7 ~]# awk 'BEGIN{arr["ceo"]="mage";arr["cto"]="laowang";print arr["cto"]}' laowang若要遍歷數(shù)組中的每個元素,要使用for循環(huán)
for(var in array){for-body}注意:var會遍歷arry的每個索引
示例:遍歷數(shù)組,可以先將數(shù)組下標(biāo)賦給i
示例2:數(shù)組的其他用法:去重
創(chuàng)建一個文件輸入以下內(nèi)容,然后執(zhí)行awk命令
此方法比較繞,讀入第一行aa作為數(shù)組line的下標(biāo),此時數(shù)組內(nèi)的值為空“假”取反后為真打印此行,然后再執(zhí)行++,此時line內(nèi)的值為1,當(dāng)再次遇到aa的行時,數(shù)組line[aa]內(nèi)有值1,取反后為假不輸出,然后再++此時[aa]內(nèi)值為2
驗(yàn)證:
示例:數(shù)組的高級用法
取連接狀態(tài)數(shù)
統(tǒng)計(jì)每個ip的連接次數(shù)
[root@centos7 ~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access_log 172.20.0.200 1482 172.20.21.121 2 172.20.30.91 29 172.16.102.29 864 172.20.0.76 1565 172.20.9.9 15 172.20.1.125 463 172.20.61.11 2 172.20.73.73 198 172.20.107.222 3 172.20.0.222 2834 172.20.111.240 4取出連接數(shù)排名前10的ip
[root@centos7 ~]# awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' access_log | sort -nr | head 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 2262 172.20.116.179 2259 172.20.65.65 1565 172.20.0.76 1482 172.20.0.200 1110 172.20.28.145小練習(xí):
統(tǒng)計(jì)男女生的平均分?jǐn)?shù)
| a | 100 | m |
| b | 99 | f |
| c | 80 | m |
| d | 98 | f |
八、字符串處理
1.length([s]):返回字符串的長度
示例:
2.sub(r,s,[t]):對t字符串搜索r表示的模式匹配的內(nèi)容,并替換為s所表示的內(nèi)容(只替換第一次匹配到的)
示例:
3.gsub(r,s,[t]):對t字符串搜索r表示的模式匹配的內(nèi)容,并全部替換為s所表示的內(nèi)容
示例:
4.splits(s,arry,[r]):以r為分隔符,切割字符串,并將切割后的字符串保存至array做表示的數(shù)組中,第一個索引值為1,第二個索引值為2,...
示例:
用函數(shù)來實(shí)現(xiàn)ip連接次數(shù)
[root@centos7 ~]# awk '/^ESTAB/{split($NF,ip,":");count[ip[1]]++}END{for(i in count){print i,count[i]}}' ss.log 192.168.172.1 465九、自定義函數(shù)
語法:
function name (parameter,parameter,...){statementsreturn experssion }示例:
awk函數(shù)定義方法
awk函數(shù)調(diào)用
[root@centos7 ~]# awk -v a=40 -v b=50 -f fun.awk 50 [root@centos7 ~]#十、awk中調(diào)用shell命令
system命令:空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用“”引用起來
示例1:調(diào)用系統(tǒng)命令
示例2:輸出變量的方法
調(diào)用雙引號輸出變量時,變量必須放在雙引號外,如果放在雙引號內(nèi),變量只會被當(dāng)作字符輸出
十一、awk腳本
awk腳本格式:
1.腳本后綴為.awk
2.腳本首行加上#!/bin/awk -f
3.給腳本添加執(zhí)行權(quán)限
示例:
十二、向awk腳本傳遞參數(shù)
使用格式:
awkfile var=value var2=value2 ... inputfile注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用。可以通過-v參數(shù),讓awk在執(zhí)行BIGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數(shù)。
示例:
創(chuàng)建一個腳本,此處以上一個腳本為例進(jìn)行修改。
轉(zhuǎn)載于:https://blog.51cto.com/11886307/2378463
總結(jié)
- 上一篇: .net core 注入中的三种模式:S
- 下一篇: 【Android AAR】1 分钟不用改