文本報告生成工具gawklinux
-----------------------------------------------------------------------------------------------------------------------------------------------
正則表達式
awk,文本報告生成工具,早期在unix上運行,如今linux上用的是gawk,GNU awk
shell
基本格式awk ‘{print}’express
打印第一域awk ‘{print $1}數組
打印第一域和第三域,中間用空格隔開awk ‘{print $1,$3}tcp
打印第一域和第三域,中間無符號隔開awk ‘{print $1 $3}ide
先打印hello,再打印第一域和第三域,最後打印bye函數
awk ‘BEGIN{print 「hello」} {print $1,$3} END{print 「bye」}工具
awk不對文件作處理時能夠用BEGIN’{……}’這種形式spa
內部變量引用外部變量:
對每一個文件有本身的編號統計,不加F則統計到一塊兒
awk -F 指明輸入時用到的分隔符,打印時沒有-F或者-v FS默認以空格爲分隔符
awk -v VAR="username" -v UID="userid" '{print USER":"$1,UID":"$3}' /etc/passwd
以空格和:做爲分隔符
內置變量
<1>變量:內置變量
<2>FS:輸入字段分隔符,默認爲空白字符
awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
awk –F: '{print $1,$3,$7}’ /etc/passwd
注:echo ‘abcd’ | awk -F "" '{print $1}',此結果$1爲a,$2爲b,-F 「」爲字符的分隔符
<3>OFS:輸出字段分隔符,默認爲空白字符
awk -v FS=‘:’ -v OFS=‘:’ '{print $1,$3,$7}’ /etc/passwd
<4>RS:輸入記錄分隔符,指定輸入時的換行符
awk -v RS=' ' ‘{print }’ /etc/passwd
<5>ORS:輸出記錄分隔符,輸出時用指定符號代替換行符
awk -v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
<6>NF:字段數量
awk -F: ‘{print NF}’ /etc/fstab,引用內置變量不用$
awk -F: '{print $(NF-1)}' /etc/passwd
NF 表示的是瀏覽記錄的域的個數
$NF 表示的最後一個Field(列),即輸出最後一個字段的內容
<7>NR:記錄號
awk '{print NR}' /etc/fstab ; awk END'{print NR}' /etc/fstab
<8>FNR:各文件分別計數,記錄號
awk '{print FNR}' /etc/fstab /etc/inittab
<9>FILENAME:當前文件名
awk '{print FILENAME}’ /etc/fstab
<10>ARGC:命令行參數的個數
awk '{print ARGC}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
<11>ARGV:數組,保存的是命令行所給定的各參數
awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab,ARGV[0]的值是awk
awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab
<12>自定義變量(區分字符大小寫)
(1)-v var=value
(2)在program中直接定義
printf輸出
<1>格式化輸出:printf 「FORMAT」, item1, item2, ...
(1)必須指定FORMAT
(2)不會自動換行,須要顯式給出換行控制符,\n
(3)FORMAT中須要分別爲後面每一個item指定格式符
printf 「格式符」,$1,$2,……
<2>格式符:與item一一對應
%c: 顯示字符的ASCII碼
%d, %i: 顯示十進制整數
%e, %E:顯示科學計數法數值
%f:顯示爲浮點數
%g, %G:以科學計數法或浮點形式顯示數值
%s:顯示字符串
%u:無符號整數
%%: 顯示%自身
<3>修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度,沒有小數第二個#能夠不寫,%3.1f,
-: 左對齊(默認右對齊) %-15s
+:顯示數值的正負符號 %+d
操做符
<1>算數操做符
+、-、*、/、%
有- x:轉換爲負數
+X:將字符串轉換爲數值
<2>字符串操做符:沒有符號的操做符,字符串鏈接
<3>賦值操做符:=,+=,-=,*=,/=,%=
<4>比較操做符:==,!=,>,>=,<,<=
<5>模式匹配符:~左邊是否和右邊匹配包含
!~:是否不匹配
<6>邏輯操做符:&&,||,!
<7>條件表達式(三目表達式)
注:判斷$3大於1000嗎?有兩個變量,大於1000輸入Common User,小於1000輸入SysUser,右對齊15個字符串長度,usertype輸出向左對齊
<8>正則表達式
<9>PATTERN:根據pattern條件,過濾匹配的行,再作處理
(1)若是未指定:空模式,匹配每一行
(2) /regular expression/:僅處理可以模式匹配到的行,須要用/ /括起來
awk '/^UUID/{print $1}' /etc/fstab
awk '!/^UUID/{print $1}' /etc/fstab
(3) relational expression: 關係表達式,結果爲「真」纔會被處理
真:結果爲非0值,非空字符串
假:結果爲空字符串或0值
(4) line ranges:行範圍
startline,endline:/pat1/,/pat2/ 不支持直接給出數字格式
awk -F: ‘/^root\>/,/^nobody\>/{print $1}' /etc/passwd
awk -F: ‘(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
(5) BEGIN/END模式
BEGIN{}: 僅在開始處理文件中的文本以前執行一次
END{}:僅在文本處理完成以後執行一次
模式匹配,正則表達式建議仍是用/,’$域 ~ /正則表達式/{print $域}’
df命令用\轉義,-F」 +|%」表示至少出現一個空格或者出現一次%
正則表達式
從b開頭到f開頭
awk控制語句
<1>{ statements;… } 組合語句
<2>if(condition) {statements;…}
<3>if(condition) {statements;…} else {statements;…}
<4>while(conditon) {statments;…}
<5>do {statements;…} while(condition):不管while條件真假,一開始do後面的執行體都會被執行一次
<6>for(expr1;expr2;expr3) {statements;…}
break
continue
delete array[index]
delete array
exit
特殊用法:可以遍歷數組中的元素
語法:for(var in array) {for-body}
<7>switch語句,awk中的case循環
語法:switch(expression) {case VALUE1 or /REGEXP/: statement1; case
VALUE2 or /REGEXP2/: statement2; ...; default: statementn}
注:default至關於shell腳本中case語句的*)
<8>break和continue
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++)
{if(i%2==0)continue;sum+=i}print sum}‘
<9>awk ‘BEGIN{sum=0;for(i=1;i<=100;i++) for循環中變量表示元素的下標,非元素的值,因此想要輸出元
{if(i==66)break;sum+=i}print sum}‘ 素的值,須要使用{print 數組名[變量名]}
<10>break [n]
<11>continue [n]
<12>next: 提早結束對本行處理而直接進入下一行處理(awk自身循環)
continue:結束本次循環,返回循環體
next:提早結束awk的本次內呈循環,這次不處理本行,直接進行下一行
break:結束全部循環
awk if語句
條件判斷
if else寫法
while循環
awk數組,鍵值對
<1>關聯數組:array[index-expression]
<2>index-expression:
(1)可以使用任意字符串;字符串要使用雙引號括起來
(2)若是某數組元素事先不存在,在引用時,awk會自動建立此元素,並將其值初始化爲「空串」
若要判斷數組中是否存在某元素,要使用「index in array」格式進行遍歷
<3>for(var in array) {for-body}
<4>注意:var會遍歷array的每一個索引,而不是array的值,好比說
awk 'BEGIN{weekday["mon"]="monday";weekday["tue"]="tuesday";for(I in weekday) {print i,weekday[i]}}'
i遍歷的是做爲weekday下標的"mon"和"tue",而不是數組weekday的值monday和Tuesday
數組舉例1
awk中若是字符串或者空字符串參與運算時,也會被當作數字0,當引用一個不存在的元素時,元素會被賦值爲空字符串
數組舉例2,統計LISTEN和ESTABLISHED的出現次數
awk每遍歷一行,就對該行最後一個字段($NF)當作索引下標來與對應的數組元素作自增操做。由於作出來的處理不能每一行都顯示,只是在最後一行顯示,所以在END處添加輸出操做
總結:作統計時,awk每遍歷一行,就對須要處理的域($0、$一、$NF)等等當作索引下標,以後讓與之對應的數組元素作自增操做(即array[域]++)。由於作出來的處理不能每一行都顯示,只是在最後一行顯示,所以在END處添加輸出操做
另:awk有一用法,awk ‘!arr[$0]++’ FILE,文件內容去重
awk函數
<1>數值處理:
rand():返回0和1之間一個隨機數
awk 'BEGIN{srand(); print rand() }'
awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }':返回0和100之間一個隨機整數
<2>字符串處理:
length([s]):返回指定字符串的長度,舉例
sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並將第一個匹配的內容替換爲s
echo "2008:08:08 08:08:08" | awk 'sub(/:/,「-",$1)'
gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,並所有替換爲s所表示的內容
echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,「-",$0)'
gsub(/被替換的字符/,」替換的字符」,域)
split(s,array,[r]):以r爲分隔符,切割字符串s,並將切割後的結果保存至array所表示的數組中,第一個索引值爲1,第二個索引值爲2,…
netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
舉例說明:split(域,數組名,」分隔符」)
<3>自定義函數
<4>格式:
function name ( parameter, parameter, ... ) {
statements
return expression
}
awk中調用shell命令
<1>system命令
<2>空格是awk中的字符串鏈接符,若是system中須要使用awk中的變量可使用空格分隔,或者說除了awk的變量外其餘一概用""引用起來。
awk BEGIN'{system("hostname") }'
awk 'BEGIN{score=100; system("echo your score is " score) }'
awk腳本
<1>將awk程序寫成腳本,直接調用或執行
<2>向awk腳本傳遞參數
<3>格式:
awkfile var=value var2=value2... Inputfile
<4>注意:在BEGIN過程當中不可用。直到首行輸入完成之後,變量纔可用。能夠經過-v 參數,讓awk在執行BEGIN以前獲得變量的值。命令行中每個指定的變量都須要一個-v參數
向awk腳本傳遞參數
<1>格式:
awkfile var=value var2=value2... Inputfile
<2>注意:在BEGIN過程當中不可用。直到首行輸入完成之後,變量纔可用。能夠經過-v 參數,讓awk在執行BEGIN以前獲得變量的值。命令行中每個指定的變量都須要一個-v參數