gawk - pattern scanning and processing language

基本用法:gawk [options] 'program' FILE ...

program:PATTERN{ACTION STATEMENTS}

語句之間用分號分隔

    print,printf
選項:
-F:指明輸入時用到的欄位分隔符;
-v var=value:自定義變數 1、print
print item1,item2,...
要點:
1.逗號分隔符;
2.輸出的各item可以字串,也可以是數值;當前記錄的欄位、變數或awk的表示式;
3.如省略item,相當於print $0;
2、變數
內建變數:
FS:input field seperator,預設為空白字元;
OFS:output field seperator,預設為空白字元;
RS:input record seperator,輸入的換行符
ORS:output record seperator,輸出時的換行符;
NF:number of field,每一行的欄位數量
NR:number of record,行數
FNR:file number of record,行檔案分別計數;
FILENAME:當前檔名;
ARGC:命令列引數的個數;
ARGV:陣列,儲存的是命令列所給定的各引數;
自定義變數:
1.-v var=value
2.在program中直接定義
3、printf命令
格式化輸出:printf FORMAT,item1,item2
(1) FORMAT必須給出
(2) 不會自動換行,需要顯式給出換行控制符,\n
(3) FORMAT中需要分別為後面的每個item指定一個格式化符號;
格式符:
%c:顯示字元的ASCII碼
%d,%i:顯示為十進位制整數
%e,%E:顯示為科技計數法
%f:顯示為浮點數
%g,%G:以科學計數法或浮點形式顯示數值
%s:顯示字串
%u:無符號整數
%%:顯示%自身
修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後的精度
%3.1f
-:左對齊
+:顯示數值的符號
4、操作符
算術執行:
x+y,x-y,x*y,x/y,x^y,x%y
-x
+x:把字串轉換為數值
字串操作符:沒有符號的操作符,字串連線
賦值操作符:
=,+=,-=,*=,/=,%=,^=
比較操作符:
>,>=,<,<=,!=,==
模式匹配:
~:是否匹配
!~:是否不匹配
邏輯操作符:
&&
||
!
函式呼叫:
function_name(argu1,argu2...)
條件表示式:
selector?if-true-expression:if-false-expression
5、PATTERN
(1) empty:空模式,匹配每一行;
(2) /regular expression/:僅處理能夠被此處的模式匹配到的行;
(3) !/regular expression/:對模式取反;
(4) relational expression:關係表示式,結果有“真”有“假”,結果為“真”才被處理;
真:結果為非0值,非空字串
(5) line ranges:行範圍
startline,endline,不支援
/pat1/,/pat2/
(NR>=2&&NR<=10)
(6) BEGIN/END模式
BEGIN{}:僅在開始處理檔案中的文字之前執行一次;
END{}:僅在文字處理完成之後命令結束之前執行一次;
6、常用action
(1) Expressions;
(2) Control statements:if,while等;
(3) Compound statements:組合語句;
(4) input statements
(5) output statements
7、控制語句
if(condition) {statements}
if(condition) {statements} else {statements}
while(condition) {statements}
do {statements} while(condition)
for (expr1;expr2;expr3) {statements}
break
continue
delete array[index]
delete array
exit
{statements} 7.1 if-else
語法:if(condition) statement [else statement]
# awk -F: '{if($3>=1000) {printf "Common user:%20s\n" $1} else { printf "root or Sysuser:%20s\n",$1}}' /etc/passwd
#awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
#awk '{if(NF>=5) print $0}' /etc/fstab
#df -h | awk -F[%] '/\/dev/{print $1}' | awk '{if($NF>=80) print $NF}'
使用場景:對awk取得的整行或某個欄位做判斷
7.2 while 迴圈
語法 while (condition) statement
條件“真”,進入迴圈:條件“假”,退出迴圈 使用場景:對一行內多個欄位進行類似處理時使用;
#awk '/^[[:space:]]*linux16/ {i=1;while(i<=NF) {print $i,length($i);i++}}' /etc/grub2.cfg
7.3 do-while 迴圈
語法:do statement while (condition)
意義:至少執行一次迴圈體
7.4 for 迴圈
語法:for (expr1;expr2;expr3) statement
for(variableassignment;condition;iteration process) {for-body}
# awk '/^[[:space:]]*linux16/ { for (i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
特殊用法:
能遍歷陣列中的元素:
語法 for (var in array) {for-body} 7.5 switch 語句
語法:switch(expression){case VALUE1 or /REGEXP:statment;case VALUE2 or /REGEXP2/: statement;...;default:statement}
7.6 break 和 continue
break [n]
continue
7.7 next
提前結束本行的處理,直接進入下一行
# awk -F: '{if ($3%2!=0) next;print $1,$3}' /etc/passwd
8、array
關聯陣列:array[index-expression]
index-expression:
(1) 可使用任意字串;
(2) 如果某陣列元素事先不存在,在引用時,awk會自動建立此元素並將其值初始化為空;
要判斷陣列中是否存在某元素,要使用"index in array"格式進行
weekdays[mon]="Monday"
# awk 'BEGIN {weekdays["mon"]="Monday";weekdays["tue"]="Tuesday" ;print weekdays["mon"]}' 若要遍歷陣列中每個元素,使用for迴圈
# awk 'BEGIN {weekdays["mon"]="Monday";weekdays["tue"]="Tuesday" ;for (i in weekdays )print weekdays[i]}'
# netstat -tan | awk '/^tcp\>/ {state[$NF]++} END { for (i in state) {print i, state[i]}}' #cat /etc/fstab | awk '/^\/dev/ {fstype[$3]++} END {for (i in fstype) print i ,fstype[i]}'
# awk '{for(i=1;i<=NF;i++) {count[$i]++} } END {for (i in count) print i,count[i]}' /etc/services
9、函式
9.1 內建函式
數值處理:
rand():返回0和1之間的一個小數
字串處理
length([s]):返回指定字串長度;
sub(r,s,[t]):以r表示的模式來查詢t所表示的字串中的匹配的內容,將將其第一次出現替換為s的內容
gsub(r,s[t]):全部替換
split(s,a[,r]):以r為分隔符切割字元s,並將切割後的結果儲存到a所表示的陣列中;
netstat -tan | awk '/^tcp\>/ {split($5,ip,":"); count[ip[1]]++} END {for (i in count) {print i,count[i]}}'
9.2 自定義函式