Linux之awk

Linux中有三種主要的文本處理工具,分別是grep,sed和awk,其中grep是文本過濾工具,sed是文本行編輯器,awk是報表生成器,今天咱們主要來探討awk。linux

awk有nawk,gawk等多種版本,如今默認linux系統下的awk是gawk,也就是咱們經常使用的awk,而在linux系統中gawk自己就是awk的連接文件,因此下文所說awk均爲gawk。shell

 

一.大體功能

awk是一種用於處理文本的編程語言工具,在不少方面相似於shell編程語言,它支持條件判斷,數組,循環等各類編程語言中全部可使用的功能,因此在必定程度上咱們能夠把awk稱爲一種腳本語言解釋器,因爲awk在處理文本的時候一次讀取一行,並根據分隔符進行切片,因此awk能夠對文本中的特定片斷進行各類加工處理,例如計數,運算等編程

 

二.用法格式

awk有三種運行方式,分別是如下三種數組

1.腳本編程語言

awk [options] ‘program’ var=value file編輯器

2.程序文件函數

awk [options] -f programfile var=value file工具

3.命令行spa

awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file命令行

 

其中的[options]:

-F 指明輸入時用到的字段分隔符

-v var=value: 自定義變量賦值

awk的前兩種運行方式直接調用文件或腳本,很少作解釋,如下重點討論awk的命令行用法

awk的命令行用法中,其格式由[options],BEGIN,pattern和END組成,其中[options]主要用於定義分隔符和定義變量,BEGIN是第一步僅且只執行一次的動做能夠不寫,pattern部分決定定動做語句什麼時候觸發及觸發事件,以及觸發什麼事件,END是最後一步僅且只執行一次的動做,也可不寫。

 

三.awk工做原理

第一步:執行BEGIN{action;… }語句塊中的語句

第二步:從文件或標準輸入(stdin)讀取一行,而後執行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件所有被讀取完畢。

第三步:當讀至輸入流末尾時,執行END{action;…}語句塊

 

BEGIN語句塊在awk開始從輸入流中讀取行以前被執行,這是一個可選的語句塊,好比變量初始化、打印輸出表格的表頭等語句一般能夠寫在BEGIN語句塊中

END語句塊在awk從輸入流中讀取完全部的行以後即被執行,好比打印全部行的分析結果這類信息彙總都是在END語句塊中完成,它也是一個可選語句塊

pattern語句塊中的通用命令是最重要的部分,也是可選的。若是沒有提供pattern語句塊,則默認執行{ print },即打印每個讀取到的行,awk讀取的每一行都會執行該語句塊

 

awk執行時,由分隔符分隔的字段(域)標記$1,$2..$n稱爲域標識

$0爲全部域,注意:和shell中變量$符含義不一樣

文件的每一行稱爲記錄

省略action,則默認執行 print $0 的操做,也就是打印整個記錄

 

四.變量

awk中變量分爲內置變量和自定義變量,自定義變量顧名思義就是咱們本身定義的變量,而內置變量則是awk爲方便咱們的使用爲咱們提早準備號的變量,在定義變量時,建議在[options]部分定義內置變量

內置變量:

FS:輸入字段分隔符,默認爲空白字符

 

OFS:輸出字段分隔符,默認爲空白字符

 

RS:輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效

 

ORS:輸出記錄分隔符,輸出時用指定符號代替換行符

 

NF:字段數量

 

NR:行號

 

FNR:各文件分別計數,行號

 

FILENAME:當前文件名

 

ARGC:命令行參數的個數

 

ARGV:數組,保存的是命令行所給定的各參數

 

自定義變量:

awk中定義自定義變量時若在[options]部分則直接用-v var=value(-v a=123)這樣的方式定義便可,若在program中定義,需用「;」隔開,因爲當value爲數值時能夠直接定義但value爲帶空格的字符串時沒法識別因此建議在定義變量時用引號將value引發

 

五.printf/print

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

 

printf

按照格式輸出,書寫時先寫目標格式,再在後面補上內容

printf格式:printf 「FORMAT」, item1, item2, ...

要點:

(1) 因爲printf是格式化輸出因此必須指定FORMAT

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

(3) FORMAT中須要分別爲後面每一個item指定格式符

格式符:與item一一對應

%c: 顯示字符的ASCII碼

%d, %i: 顯示十進制整數

%e, %E:顯示科學計數法數值

%f:顯示爲浮點數

%g, %G:以科學計數法或浮點形式顯示數值

%s:顯示字符串

%u:無符號整數

%%: 顯示%自身

修飾符:

#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f 表示一個三位的一位小數的浮點數

-: 左對齊(默認右對齊) %-15s 表示這一部分左對齊並去字符寬度爲15,不足則空格補齊

+:顯示數值的正負符號 %+d

示例:

awk -F: ‘{printf "%s",$1}’ /etc/passwd

awk -F: ‘{printf "Username: %s\n",$1}’ /etc/passwd
awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}’ /etc/passwd

 

六.操做符

awk中支持各類操做符

算術操做符:

x+y, x

-y, x*y, x/y, x^y, x%y

-x: 轉換爲負數

+x: 轉換爲數值

賦值操做符:

=, +=,

-=, *=, /=, %=, ^=

++, --

邏輯操做符:與&&,或||,非!

比較操做符:

==, !=, >, >=, <, <=

模式匹配符:

~:左邊是否和右邊匹配(!~:是否不匹配)其中右邊要匹配的部分要用「」或者//括起來

awk–F: ‘$0 ~ /root/{print $1}’ /etc/passwd

awk ‘$0~「^root"' /etc/passwd

awk ‘$0 !~ /root/’ /etc/passwd

 

七.awk action

awk有如下幾種經常使用action

(1) Expressions:算術,比較表達式等

(2) Control statements:if, while等

(3) Compound statements:組合語句

(4) input statements

(5) output statements:print等

因爲其餘的action在上面都有介紹因此這裏主要講述控制語句而組合語句則是多種action的組合

 1.控制語句if-else

if語句經常使用於對awk取得的某個字段進行條件判斷

格式:if(condition1){statement1}else if(condition2){statement2}

else{statement3}

例如:

awk讀取/etc/passwd 輸出系統用戶和普通用戶

awk -F: ‘{if($3>=1000) {printf "Common user: %s\n",$1} else {printf

"root or Sysuser: %s\n",$1}}' /etc/passwd

2.控制語句while

while經常使用於對同行內多個字段逐一處理和對數組個元素逐一處理

格式:while(condition){statement;…}

例如:

awk讀取/etc/grub2.cfg 輸出以任意空格加linux16做爲開頭的行的全部字段的長度

其中length()是一個awk的內置函數

awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i); i++}}’ /etc/grub2.cfg

3.控制語句for

for語句功能和while基本相同,一樣可用於遍歷數組

格式:for(variable assignment;condition;iteration process) {for-body}

例如:

for代替上面的while輸出以任意空格加linux16做爲開頭的行的全部字段的長度

awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

4.控制語句break/continue/next

awk中的break和continue同shell腳本中的功能同樣,break跳出當前層的循環,continue跳過本次循環直接進入下一次,固然能夠在break和continue跟上數字以表示跳出的循環個數,默認爲1.而next則是跳出awk自己的循環,即直接進入下一行的循環。

例如:

awk '{for (i=1;i<3;i++){if (i==2){break}else{print i}}}' /etc/passwd這個循環中break直接跳出當前的for循環直接進入下一行的循環,若是把break換成continue則是跳出本次循環,直接進入i=3時的循環而後才進入下一行的循環。若是把break換成next則是直接進入下一行的循環,因爲這個awk語句中除了awk自己的循環只有一層循環因此在這條語句中break和next做用相同。

 

八.數組

awk中數組一般是以字符串爲下標的,其他和shell腳本中的數組基本相同

awk的數組通常寫在pattern中,以遍歷整個文件,而後在END中經過循環輸出咱們的數組

例如:

計算/etc/passwd中各類默認shell的個數,其中默認shell是這個文件每行的第七個域,在pattern部分直接以默認shell爲數組下表,在awk循環遍歷整個文件時,每遇到一種shell就在line數組中建立一個對應的下標,並讓這個下標對應的值加一,以後每遇到一次都加一,而後在END部分經過for循環遍歷輸出每一個下標及其對應的值,也就是出現的次數

awk -F: ‘{line[$7]++}END{for(i in line){print i,line[i]}}' /etc/passwd

相關文章
相關標籤/搜索