Linux AWK用法
awk:報告生成器,格式化文本輸出
gawk:模式掃描和處理語言
基本語法:
options:選項
program:awk的語言
var=value:賦值給var
file:參數
awk [options] 'program' var=value file...
awk [options] -f programfile var=value file...
awk [options] 'BEGIN{action} pattern{ action;...}END{action;...}' file..
選項:
-F 指定分隔符
-v var=value:自定義變量
awk語言
基本格式:awk [options] 'program' file....
program:pattern{action statements;...}
pattern和action:
pattern部分決定動作語句何時觸發及觸發事件
BEGIN:文件處理之前就執行一個動作
END:當所有文件處理結束後執行一個動作
action statements對數據進行處理,放在{}內指明
print,printf
分隔符、域和記錄
awk執行時,由分隔符分隔的字段(域)標記$1,$2...$n成為域標識;$0為所有域
文件的每一行稱為記錄,也可以用別的作為記錄的分隔符
省略action,默認執行print $0
awk工作原理
第一步:如果有BEGIN{action;...}優先執行BEGIN
第二步:從命令的執行結果或者文件讀取一行,然後執行pattern{action;...},逐行處理
第三步:執行END{action;....}
awk
item=要打印的字符
print格式:print item1,item2,...
註意:
(1)逗號分隔符
(2)輸出的各item可以字符串,也可以是數值;當前記錄的字段、變量或awk的表達式
(3)如省略item,相當於print $0
awk變量
field 域,字段,列column,屬性(一個意思)
行,記錄,record(一個意思)
變量:內置和自定義變量
使用變量時,需添加-v選項
FS:字段的分隔符,默認為空白字符
awk -v FS=':' '{print $1,FS,$2}' passwd (指定FS變量值為:打印passwd文件的第一列和第二列,逗號是作為空白符的)
OFS:輸出分隔符的定義
awk -v OFS="+" '{print $1,$2}' passwd(指定OFS變量值為+,打印passwd文件的第一列和第二列,輸出分隔符是+)
RS:指定分開記錄的分隔符
記錄:默認回車換行算一條記錄
awk -v RS=";" '{print $2}' f1.txt中的值為 aa bb cc;ee
ff oo;xx
yy zz (指定RS變量值為;打印f1.txt文件的第二列,結果為bb ff yy)
ORS:指定記錄輸出的分隔符
awk -v RS=" " -v ORS="###" '{print}' passwd(默認以回車換行區分每條記錄,ORS指定區分每條記錄的分隔符)
NF:字段個數
awk -F: '{print NF}' passwd(逐行處理,顯示的全是7)
awk -F: '{print $NF}' passwd(逐行處理,顯示第7列的數據,因為NF是7)
awk -F: '{print $(NF-1)}' passwd(逐行處理,顯示7-1列的數據)
NR:記錄號
awk '{print NR,$0}' passwd(逐行處理,每一行都打印,並且顯示每一行的行號)
FNR:文件分別計數
awk '{print FNR,$0}' /etc/fstab /etc/issue(兩個文件分別顯示所有行並且顯示行號)
FILENAME:當前文件名
awk '{print FNR,FILENAME,$0}' /etc/fstab /etc/issue(兩個文件分別顯示所有行並且在前面顯示文件名稱)
ARGC:參數個數
awk '{print ARGC}' /etc/fstab /etc/issue(查看awk的參數)
ARGV:數組,顯示命令行awk算第一個參數,跳過print部分,後續為第二個參數,第三個參數
awk '{print ARGV[0]}' /etc/fstab /etc/issue
print中也可以定義變量
awk的-f選項可以讀取文件,文件中寫入的是'{print}'等一系列數據
printf命令
格式化輸出:printf "FORMAT",item1,item2,....
(1)必須指定FORMAT
(2)不會自動換行,需要顯示給出換行控制符,\n
(3)FORMAT中需要分別為後面每個item指定格式符
格式符:與item一一對應
%c:顯示字符的ASCII碼
%d,%i:顯示十進制整數
%e,%E:顯示科學計數法數值
%f:顯示為浮點數
%g,%G:以科學計數法或浮點形式顯示數值
%s:顯示字符串
%u:無符號整數
%%:顯示%自身
修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後精度,%3.1f
-:左對齊(默認右對齊) %-15s(前面空出15個寬度並且左對齊顯示)
+:顯示數值的正負符號%+d
操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 轉換為負數
+x: 轉換為數值
賦值操作符:
=, +=, -=, *=, /=, %=, ^=
++, --
比較操作符:
==, !=, >, >=, <, <=
模式匹配符:
~:左邊是否和右邊匹配包含 !~:是否不匹配
可以使用擴展的正則表達式,""中寫正則表達式,或者//中寫正則表達式
例子:awk –F: '$0 ~ /^root/' /etc/passwd 匹配文件中以root開頭的行
awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd (打印匹配第三個字段大於0並且第三個字段小於1000)
awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd (打印匹配第三個字段等於0或者第三個字段大於1000)
awk -F: '!($3==0){print $1}' /etc/passwd (打印第三個字段不等於0的行)
awk -F: '!($3>=500){print $3}' /etc/passwd (打印第三個字段不等於500的字段的行)
awk當中變量為""為假,為0的時候為假,有值則為真
條件表達式(三目表達式:用三個表達式,分別用?:分開分成三段)
例子:awk -F: '{$3>=1000?usertype="common user":usertype="sysuser";printf "%-15s:%-30s %d \n",usertype,$1,$3}'
awk PATTERN
PATTERN:就是花括號前面的部分
(1)如果沒有指定:空模式,匹配每一行
(2)/正則表達式/
(3)關系表達式,結果為真才會被處理
真:結果為非0值,非空字符串
加:結果為空字符串或0值
(4)line ranges:行範圍
'/條件/,/條件/' 第一個條件必須要匹配,第二個條件沒有的話則會匹配到結尾
(5)BEGIN/END模式
BEGIN{}:處理文件之前處理一次
END{}:在文件處理完成之後處理一次
awk action
常用的action分類
(1)算數,表達式
(2)if,while等
(3)組合語句就是?:分開的
(4)輸入語句
(5)輸出:print
if語句
語法:if(表達式){執行的操作;....}[else 執行操作]
while循環:當字段個數過多並且都要執行的時候可以使用
語法:while(表達式){執行的操作;...}
條件"真",進入循環;條件"假"退出循環
do-while循環
語法:do{執行操作;}while(表達式)
意義:無論真假,至少執行一次
next:
提前結束對本行處理而直接進入下一行處理(awk自身循環)
awk數組
關聯數組:array[下標自定義]
(1)可使用任意字符串;字符串要用雙引號括起來
awk '!arr[$0]++' 文件名(去掉重復行操作)
遍歷數組.
for(var in array){for-body}
awk '{IP[$1]}END{for(i in IP)print i,IP[i]}' /var/log/access_log 統計IP地址的連接次數
awk函數
數值處理:
rand():返回0和1之間的一個隨機數,但是如果單獨打印rand()是不能生成隨機數的與srand()函數結合使用,默認生成的浮點數,生成整數如下
例子:awk 'BEGIN{srand();print int(rand()*100)}':生成隨機整數
字符串處理:
length("指定字符串"):返回指定字符串長度
sub(r,s,要處理的字符串):對要處理的字符串進行搜索r表示修改的字符串,s是修改後的字符串,只替代第一個匹配到的
gsub:是將匹配到的全部替換
split(s,arry,r):對字符串s進行切割,使用r作為分隔符,將切割後的結果保存到arry的數組中,成為了數組的值
自定義函數
格式:
function "name" (參數1,參數2,.....相當於shell的$1,$2,$3....){
代碼
return "表達式"
}
調用的參數是實際參數,命名的時候是形式參數;實際參數和形式參數的名稱可以不同,但數量要相同
使用system調用bash命令
例子:awk BEGIN'{system("hostname")}'
如果是awk中定義的變量awk要用system的echo調用的話將命令加入到雙引號中
Linux AWK用法