awk快速入门
AWK快速入門
awk簡介
awk是一個優良的文本處理工具,是Linux中文本三劍客之一,awk的名字取自于其創始人Alfred Aho、Peter Weinberger和Brain Kernighan三人姓式的首字母。
awk的功能及其強大,可以進行式樣裝入、流控制、數學運算符、進程控制語句甚至內置的變量和函數,他具備了一個完整語言所應有的幾乎所有特性。
awk語法
awk程序由BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成
awk [option] '[BEGIN{action;...}]pattern{action;...}[END{action;...}]' file| -F | 指定分隔符 |
| -f | 指定awk程序文件 |
| -v | 變量賦值,每個變量都需要使用-v var=value來賦值 |
awk工作原理
1.執行BEGIN{action;...}語句塊中的語句
BEGIN語句塊在awk開始從輸入流中讀取的行之前被執行,這是個可選的語句塊,
2.從文件或標準輸入中讀取一行,然后執行pattern{action;...}語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
3。當讀至輸入流末尾時,執行END{action;...}語句塊。
END語句塊,在awk從輸入流種讀取完所有的行之后再執行,比如打印所有行的分析結果這里信息匯總都是在END語句中完成,它也是個可選語句塊
awk基本用法
awk最簡單的使用方法為:
awk [option] 'pattern{action;...}' file一、print
print的參數可以是變量、數值或字符串。字符串必須用雙引號引用,參數用逗號分隔。如果沒有逗號,參數就串聯在一起,無法區分。這里逗號的作用與輸出文件的分隔符所用是一樣的,只是后者是空格而已。當pattern不指定時默認打印文件中所有的行。
示例1:打印/etc/fstab中的每一行
二、awk變量
awk有內置變量和自定義變量
內置變量有FS、OFS、RS、ORS、NF、FNR、FILENAME、ARGC、ARGV
1.FS:設置輸入域分隔符,等價于命令行選項-F
示例1:使用變量FS指定分隔符,取出/etc/fstab的第1第3列
[root@centos7 ~]# awk -v FS=: '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...示例2:使用選項-F指定分隔符,取出/etc/fstab的第1第3列
[root@centos7 ~]# awk -F":" '{print $1,$3}' /etc/passwd root 0 bin 1 daemon 2 ...以下省略...示例3:用正則表達式當分隔符取出分區利用率
[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:設置輸出時域分隔符,默認為空白
示例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:設置記錄分隔符
當記錄的分割符指定為某符號時,從字符開始至記錄分隔符的字符串為一條記錄,記錄的條數和行數無關。
示例1:創建一個文本指定;為分隔符查看記錄情況。
以上面文件內容為例,以分號為記錄的分隔符,此文件一共有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:設置輸出時記錄分隔符
ORS變量指定輸出時的記錄分隔符為什么符號。
示例:
依舊為a.txt文件,設置分隔符為,號,紀錄分隔符為;號,輸出時設置記錄分分隔符為___,取出第一字段。
5.NF:域數
NF可以查看一條記錄內有多少個域,也可以用來查看倒數第N個字符為什么
示例1:
以/etc/passwd為例,以:號為分隔符查看每行的字段數量
示例2:
差看/etc/passwd文件內,以:為分隔符,倒數第2個字段的內容
6.NR:記錄數
NR變量為已讀文件的記錄數
示例1:
以;為記錄符,在a.txt的文件的每條記錄前加上記錄行。
NR變量還可以合并計數多個文件的記錄
示例2:查看/etc/fstab和/etc/issue總共有多少記錄號
7.FNR:文件的記錄數
FNR變量為每個文件分別記錄記錄數。
示例:查看/etc/fstab和/etc/issue的記錄數
8.FILENAME:文件名
FILENAME變量為輸出文件名
示例:在匹配到的行后面加上文件名
9.ARGC:命令行參數個數
ARGC變量存放的為參數個數。
示例:
顯示為2個參數,是哪兩個參數呢?看下面那個函數
10.ARGV:查看命令行參數
ARGV變量為一個數組里面存放的為awk的每個參數
示例:
打印每一個參數
自定義變量
自定義變量的賦值有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中直接定義
把變量賦值放在{}內,把變量放在{}內賦值時變量值必須要加雙引號,變量必須先賦值再引用,次序錯誤會導致第一次匹配到的行沒有值
示例1:在每個用戶前加上ceo
示例2:調用腳本文件
awk '{action}' 單引號內的腳本可以存放在文件內被調用
三、printf
printf格式化輸出:
printf "FORMAT" ,item1,item2,...| %c | 顯示字符的ASCII碼 |
| %d,%i | 顯示十進制整數 |
| %e,%E | 顯示科學計數法數值 |
| %f | 顯示浮點數 |
| %g | 以科學計數法或浮點形式顯示數值 |
| %s | 顯示字符串 |
| %u | 無符號整數 |
| %% | 顯示%自身 |
| #[.#] | 第一個數字控制顯示的寬度;第二個#標識小數點后精度,%3.1f |
| - | 左對齊(默認為右對齊)%-15s |
| + | 顯示數值的正負值符號%+d |
示例1:
%d打印整數
示例2:
格式符有幾個對應的item項就要就幾個否則語法錯誤
示例3:
%f可以打印小數,默認輸出的為6位。也可以指定小數位。
示例4:
.之前的數字為長度(默認右對齊)
示例5:
指定左對齊,在%后面加上-
四、操作符
awk還支持各種操作符如算數操作符、字符串操作符、賦值操作符、比較操作符、模式匹配操作符
1.算數操作符
算數操作符有+、-、、/、^、%,如:
x+y,x-y,xy,x/y,x^y,x%y
示例1:
簡單的算術運算
示例2:
-x:轉換為負數
2.賦值操作符:
賦值操作符有:=,+=,-=,*=,/=,%=,^=,++,--
示例1:
3.比較操作符和模式匹配符
比較操作符和模式匹配符常用在awk的行過濾pattern中,Pattern為空時所有都符合條件
pattern中可以添加比較符號和模式匹配
比較符號有:==(等于),!=(不等于),>(大于),>=(大于等于),<(小于),<=(小于等于)
模式匹配符:~(符號左邊內容是否右邊匹配內容,包含內容),!~(符號左邊內容的是否不匹配右邊內容)
模式匹配時可以使用正則表達式!
3.1比較操作符示例
示例1:
取出連接主機的IP
示例2:
取出用戶列表中UID大于1000的用戶和ID
示例3:
取出ip地址
示例4:
取出分區利用率大于10的設備
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結尾的行
示例2:
取出分區利用率大于10的設備名和分區利用率
示例3:
取出連接數前3的IP地址
5.三目表達式
三目表達式格式:
selector?if-ture-expression:if-false-expression
判斷selector是否為真,如果為真則執行if-ture語句,不為真則執行if-false語句。
示例1:
在Uid大于等于1000的用戶前添加commom user,小于1000的添加system user
五、PATTERN部分總結
PATTEN:awk在執行時會根據pattern條件,過濾匹配的行,再做處理。
pattern的條件可以有以下幾種:
1.空
如果pattern部分為空,則默認匹配每一行
示例:打印所有行
2.正則表達式
/regular expression/:僅處理能夠被模式匹配到的行,需要用//括起來
示例:找出/etc/passwd中以g開頭的行的第1字段和第3字段
3.關系表達式
relational expression: 關系表達式,結果為“真”才會被處理
真和假的定義:
3.1真:結果為非0值,非空字符串
示例1: 當有值時為真,輸出所有。
示例2:當數字為負數時,輸出也為真
[root@centos7 ~]# seq 3 | awk '"-1"' 1 2 3示例3:當中間的數字為空格時也為真
[root@centos7 ~]# seq 3 | awk '" "' 1 2 33.2假:結果為空字符串或0值,假則不會被處理
示例1:當值為空和0時不做輸出
示例2:在awk中不加字符不添加雙引號表示為變量,變量為空和0時也為假,變量中有值時為真
[root@centos7 ~]# seq 5 | awk 'i' #變量中沒有值,假 [root@centos7 ~]# seq 5 | awk -v i=1 'i' #變量中有值,真,輸出結果 1 2 3 4 54.行范圍
pattern可以使用行范圍進行匹配
/pat1/,/pat2/ 不支持直接給出數字格式
示例:打印b開頭的行到f開頭的行
5.BEGIN/END模式
BEGIN{}:僅在開始處理文件中的文本之前執行一次
END{}:僅在文本處理完成之后執行一
示例1:使用BEGIN來添加表頭,做格式化輸出。
六、awk控制語句
流程控制語句是任何程序設計語言都不能缺少的部分。任何好的語言都有一些執行流程控制的語句。awk提供的完備的流程控制語句類似于C語言,這給我們編程帶來了極大的方便。
awk控制語句有:if-else,while循環,do-while循環,for循環,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為偶數則打印出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循環
使用場景:
1.對一行內的多個字段逐一類似處理時使用
2.對數組中的各元素逐一處理時使用
語法:
條件為真進入循環,條件為假退出循環。
示例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循環
常用語法:
for(expr1;expr2;expr3){statement;...}特殊用法:便利數組中的元素
語法:
示例1:for循環1+到100
[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum+=i}print sum}' 50504.break和continue
break為提前結束循環
continue為提前結束本次循環,進入下一次循環
示例:將1到100的偶數相加
1-100的偶數相加,當i=50時跳出不加,繼續執行后續循環
[root@centos7 ~]# awk 'BEGIN{for(i=1;i<=100;i++){if(i==50){continue};if(i%2==0){sum+=i}}print sum}' 25001-100的偶數相加,當i=50時跳出所有循環
[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是提前結束對本行的處理直接進入下一行的處理,next跳出的是awk自身的循環。
示例:
打印Uid為偶數的行
七、awk數組
awk數組為關聯數組:array[index-expression]
index-expression為數組下標
數組在使用時需注意以下幾點:
1.數組下標可使用任意字符串;字符串要使用雙引號括起來
2.如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其初始化為“空串”
3.若要判斷數組中是否存在某元素,要時用“index in array”格式進行遍歷
示例:給數組賦值,和輸出數組
[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若要遍歷數組中的每個元素,要使用for循環
for(var in array){for-body}注意:var會遍歷arry的每個索引
示例:遍歷數組,可以先將數組下標賦給i
示例2:數組的其他用法:去重
創建一個文件輸入以下內容,然后執行awk命令
此方法比較繞,讀入第一行aa作為數組line的下標,此時數組內的值為空“假”取反后為真打印此行,然后再執行++,此時line內的值為1,當再次遇到aa的行時,數組line[aa]內有值1,取反后為假不輸出,然后再++此時[aa]內值為2
驗證:
示例:數組的高級用法
取連接狀態數
統計每個ip的連接次數
[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取出連接數排名前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小練習:
統計男女生的平均分數
| a | 100 | m |
| b | 99 | f |
| c | 80 | m |
| d | 98 | f |
八、字符串處理
1.length([s]):返回字符串的長度
示例:
2.sub(r,s,[t]):對t字符串搜索r表示的模式匹配的內容,并替換為s所表示的內容(只替換第一次匹配到的)
示例:
3.gsub(r,s,[t]):對t字符串搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
示例:
4.splits(s,arry,[r]):以r為分隔符,切割字符串,并將切割后的字符串保存至array做表示的數組中,第一個索引值為1,第二個索引值為2,...
示例:
用函數來實現ip連接次數
[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九、自定義函數
語法:
function name (parameter,parameter,...){statementsreturn experssion }示例:
awk函數定義方法
awk函數調用
[root@centos7 ~]# awk -v a=40 -v b=50 -f fun.awk 50 [root@centos7 ~]#十、awk中調用shell命令
system命令:空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用“”引用起來
示例1:調用系統命令
示例2:輸出變量的方法
調用雙引號輸出變量時,變量必須放在雙引號外,如果放在雙引號內,變量只會被當作字符輸出
十一、awk腳本
awk腳本格式:
1.腳本后綴為.awk
2.腳本首行加上#!/bin/awk -f
3.給腳本添加執行權限
示例:
十二、向awk腳本傳遞參數
使用格式:
awkfile var=value var2=value2 ... inputfile注意:在BEGIN過程中不可用。直到首行輸入完成以后,變量才可用。可以通過-v參數,讓awk在執行BIGIN之前得到變量的值。命令行中每一個指定的變量都需要一個-v參數。
示例:
創建一個腳本,此處以上一個腳本為例進行修改。
轉載于:https://blog.51cto.com/11886307/2378463
總結
- 上一篇: .net core 注入中的三种模式:S
- 下一篇: 转换