文本處理器awk

awk:linux


文本處理三劍客:grep,sed,awk;express

grep系:grep,egrep,fgrep;基於pattern進行過濾文本;數組

sed:流編輯器,行編輯器;模式空間,保持空間;bash

awk:報告生成器,格式化文本輸出;編輯器


AWK:ide

Alfred Aho,貝爾實驗室;函數

Peter J Weinberger,貝爾實驗室;spa

Brian Kernighan,貝爾實驗室,K&R命令行


CentOS RHEL系awk,GNU AWK,gawk;regexp

Debian系awk,New awk,nawk


GNU awk——gawk

gawk - pattern scanning and processing language

基本格式:

awk [options] 'program' file...


program:pattern{action statements;...}

pattern:部分決定動做語句什麼時候觸發及經過什麼事件來觸發;

BEGIN,END

action statement對數據進行處理,一般放在一對{}之中;

print,printf


分隔符:awk對數據進行處理時,會根據特定的標識對數據進行分段,這種特定標識就是分隔符,默認是空白字符;


字段:通過分隔符分隔以後的每個分段,都稱爲一個字段(Field);默認awk會使用內置位置變量來存儲各個字段的值;這些變量就是$1,$2,...$N;


記錄:有換行符分隔的數據中的每一行,就是一個記錄;在awk處理數據時,使用$0保存整行的內容;


awk工做原理:

1.首先,執行BEGIN{action statements}語句塊中的語句;

2.其次,從文件中或者從標準輸入讀取一行,而後執行pattern{action statements}語句塊;逐行重複處理該過程,直到數據所有被讀取完畢;

3.在其餘語句執行完成後,在退出awk程序以前,執行END{action statements}語句塊;


注意:

1).BEGIN語句塊在awk開始處理數據以前就須要執行;此語句塊是可選語句塊;

2).END語句塊在awk處理完全部的數據以後,纔會被執行;此語句塊是可選語句塊;

3).pattern語句塊中的通用命令是最重要的部分,也是可選的;若是沒有提供pattern語句塊,則默認執行{ print }語句,顯示數據的每一行;awk讀取到的每一行都會執行一次pattern語句塊的內容;


awk的基本用法:

經常使用選項:

-F:用來指明這次數據處理的字段分隔符,默認爲空白字符;

-v var=value:用於自定義變量和爲自定義變量賦初始值;


經常使用的ACTION:

1.print:標準格式顯示;

print item1,item2,...


print命令的要點:

a.逗號分隔;

b.輸出的各item能夠是字符串,能夠是數字,能夠是當前記錄中的字段,能夠是變量,能夠是awk表達式;

c.若是省略了item,就輸出整行,至關於{print $0};


示例:

~]# awk -F: '{print $1,$3,$7}' /etc/passwd

~]# echo -e "1 2 3\n4 5 6\n7 8 9" | awk '{print $2}'


2.變量:

       內建變量:

FS:input field seperator,輸入字段分隔符,默認空白字符;

示例:

~]# awk -v FS=':' '{print $1}' /etc/passwd


OFS:outpit field seperator,輸出字段分隔符,默認空白字符;

示例:

~]# awk -v FS=':' -v OFS=':' '{print $1,$3}' /etc/passwd


RS:input record seperator,輸出記錄分隔符,換行;

注意:即便指定了新的輸出記錄分隔符,即變爲換行;

示例:

~]# awk -v RS='/' '{print $0}' /etc/passwd


ORS:output record seperator,輸出記錄分隔符;不換行


NF:number of field,字段數量;

示例:

~]# awk -v FS=':' '{print NF}' /etc/passwd

~]# awk -v FS=':' '{print $NF}' /etc/passwd

~]# awk -v FS=':' '{print $(NF-1)}' /etc/passwd


NR:number of record,行數;鑑於awk遍歷文件每行的特性,能夠將該變量理解爲行號;

示例:

~]# awk  '{print NR}' /etc/passwd


FNR:file number of record,分別統計各個文件的行數,行號;

示例:

~]# awk  '{print FNR}' /etc/passwd /etc/fstab


FILENAME:輸出當前正在處理的文件的文件名;每行顯示一個;

示例:

~]# awk  '{print FILENAME}' /etc/passwd /etc/fstab


ARGC:argument count,整個命令行中的參數的數量;包括命令自己;

示例:

~]# awk  '{print ARGC}' /etc/passwd /etc/fstab /etc/issue


ARGV:數組,argument value,保存了命令行中各個參數的具體內容;

示例:

~]# awk  '{print ARGV[1]}' /etc/passwd /etc/fstab /etc/issue


自定義變量:

定義方式:

-v var=value

注意:變量名區分字符大小寫;


示例:

~]# awk -v var1='hello' -F: '{print var1 ,$1}' /etc/passwd


3.printf命令:

格式化輸出命令:printf "FORMAT" item1,item2,...


要點:

1) 必須給出合適的FORMAT;

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

3) FORMAT中須要爲後面的每個item指定一個格式化符號;


格式符:

%c:顯示字符的ASCII碼;

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

%f:顯示浮點數字;

%e,%E:使用科學計數法顯示數字;

%g,%G:使用科學計數法顯示浮點數字;

%s:顯示字符串;

%u:顯示無符號整數;

%%:顯示%自身;


修飾符:

#[.#]:第一個數字用來控制顯示寬度;第二個數字表示小數點的精度;

如:%3.1f  %5s

-:表示採用左對齊機制;默認是右對齊; %-15s

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


示例:

~]# awk -F: '{printf "%-20s: %-5s\n",$1,$3}' /etc/passwd


4.操做符:

算術操做符:

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

-x:將正數轉換爲負數;

+x:將字符串轉換爲數值;


字符串操做符:

沒有符號的操做符,表示字符串鏈接之意;


賦值操做符:

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

++, --


比較操做符:

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


模式匹配操做符:

~:左側的字符串是否可以被右側的模式所匹配;

!~:左側的字符串是否不可以被右側的模式所匹配;


示例:

~]# awk -F: '$3==1000{print $0}' /etc/passwd

~]# awk -F: '$NF~/bash/{print $0}' /etc/passwd


邏輯操做符:

&&

||

!


示例:

~]# awk -F: '$3>=500&&$3<=1000{print}' /etc/passwd


條件表達式:

condition(selector)?if-true-expression:if-false-expression


示例:

~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Super or System User";printf "%-20s: %-20s\n",usertype,$1}' /etc/passwd


5.PATTERN:

1) empty:空模式,處理文件中的每一行;

2) [!]/REGEXP/:僅處理[不]能被PATTERN匹配到的行;

示例:~]# awk '[!]/^r/{print}' /etc/passwd

3) 關係表達式:$3>=1000, $NF~/bash/

4) 行的範圍:

關係表達式:($3>=500&&$3<=1000)

/regexp1/,/regexp2/:從被regexp1匹配的行開始到被regexp2匹配的行結束,有多少這一類匹配結果,就顯示多少次;


示例:~]# awk '/^r/,/^a/{print}' /etc/passwd

5) BEGIN/END模式:

BEGIN{}:僅在開始處理文件中的第一行文本以前執行一次的語句塊;

示例:

~]# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}' /etc/passwd

注意:在輸出特定格式的表頭時,經常使用此語句塊;


END{}:僅在文本處理完成但命令還沒有退出時執行一次的語句塊;

示例:

~]# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}END{print "========================\n",NR " users"}' /etc/passwd


6.經常使用的ACTION:

1.表達式(Expression)

2.組合語句(Cpmpound Statement)

3.輸入語句(Input Statement)

4.輸出語句(Output Statement)

5.控制語句(Control Statement)


7.控制語句:

if (condition) statement [ else statement ]

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

delete array[index]

delete array

exit [ expression ]

{ statements }

switch (expression) {case value|regex : statement...[ default: statement ]}


1) if-else:

語法:if (condition) {statement} [ else {statement} ]

使用場景:對awk取得的整行或某個字段作條件判斷;


示例:

~]# awk -F: '{if($3>=1000) {print $1} else {print $1,$3}}' /etc/passwd


2) while循環:條件爲真,進入循環;條件爲假,退出循環;

語法:while (condition) statement

使用場景:對一行內的多個字段逐一作相似的處理時;對數組中的各個元素遍歷及處理時;


示例:

~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%s: %d\n",$i,length($i);i++}}' /etc/grub2.cfg 


3) do...while循環:

語法:do statement while (condition)

意義:同while循環,但至少執行一次循環體中的語句;


4) for循環:

語法:for (expr1; expr2; expr3) statement

expr1:變量賦初值;

expr2:條件判斷;

expr3:變量值的遞增或遞減調整;


示例:

~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {printf "%s: %d\n",$i,length($i)}}' /etc/grub2.cfg 

5) break 和 continue

break [n]

continue:跳過本次循環,直接進入下次循環;


6) next語句:

提早結束對本行的處理,而直接進入下一行;

示例:

~]# awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd


8.數組(Array)

關聯數組:array[index_expression]

index_expression:

1) 可使用任意的字符串,字符串必須使用雙引號;

2) 若是某數組元素事先不存在,當引用該元素時,awk會自動建立此元素,而且爲該元素賦"空字符串"做爲其初始值;空字符串取值爲0


注意:若是想要判斷數組中某個元素是否存在,通常會使用"index in array"格式進行;    index in array:數組索引name


示例:

~]# awk 'BEGIN{name["leader"]="zhang";name["mem1"]="li";name["mem2"]="wang";print name["leader"]}'


查看已鏈接狀態下,同一客戶端的鏈接數量:

~]# ss -tn | awk '/^ESTAB\>/{print $NF}' | awk -F: '{state[$1]++}END{for(s in state){print state[s],s}}'


9.函數:

內建函數:

length():計算字符串長度

split(string,array[,fieldsep])


示例:

~]# awk '{split($0,user,":");print user[1]}' /etc/passwd


自定義函數:

相關文章
相關標籤/搜索