基本用法:
awk '{pattern + action}' filename
pattern: 查找的内容或者正規表達式
action: 找到比對内容後,所執行的一系列指令
awk調用的3種方式:
1.指令行方式
awk [-F filed-separator] 'commands' input-file(s)
其中,commands是真正的awk指令,[-F域分隔符]是可選的,input-file(s)是待處理的檔案。
在awk中,檔案的每一行中,由域分隔符分開的每一項都為一個域。
不指定-F域分隔符的話,預設的分隔符都是空格。
2.shell腳本方式
将所有的awk指令插入一個檔案,并使用awk程式去執行。需要注意的是:必須将awk指令解釋器
作為腳本的首行(#!bin/awk)。相當于shell腳本首行的:#!bin/sh
3.将所有的awk指令插入到一個單獨檔案,然後調用.
awk -f awk-script-file input-file(s)
其中,-f選項是加載awk-script-file檔案,input-file(s)是待處理的檔案。
舉例說明:
1.顯示最近登入的5個賬号名稱: last -n 5
1)顯示最近登入的5個賬号資訊
[[email protected] ~]$ last -n 5
hduser04 pts/52 10.50.116.84 Thu Sep 8 10:48 still logged in
ex-wugua pts/4 10.13.96.106 Thu Sep 8 10:37 still logged in
ex-zhoub pts/51 10.13.96.117 Thu Sep 8 10:29 still logged in
ex-zhoub pts/13 10.13.97.152 Thu Sep 8 10:23 still logged in
ex-zhoub pts/13 10.13.97.152 Thu Sep 8 10:22 - 10:23 (00:00)
2)隻顯示賬号
[[email protected] ~]$ last -n 5 | awk '{print $1}'
hduser04
ex-wugua
ex-zhoub
ex-zhoub
ex-zhoub
awk工作的流程是這樣的: 讀入有'\n'換行符分隔的一條記錄,然後将記錄按指定的域分隔符劃分。
$0表示所有域(即整條記錄),$1表示第1個域,$n表示第n個域。預設域分隔符為"空白鍵"或者"tab鍵"。
是以上面的$1表示登入使用者,$3表示IP,以此類推.
2.隻顯示/etc/passwd的賬戶
cat /etc/passwd | awk -F ':' '{print $1}'
awk -F ':' '{print $1}' /etc/passwd
3.隻顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以tab鍵分隔
cat /etc/passwd | awk -F ':' '{print $1"\t"$7}'
awk -F ':' '{print $1"\t"$7}' /etc/passwd
4.隻顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以逗号鍵分隔,并且添加列名(name,shell),
末尾添加'blue,/bin/nosh'
awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}' /etc/passwd
awk工作的流程是這樣的: 先執行BEGIN,然後讀取檔案,讀入有'\n'換行符分隔的1條記錄,然後将記錄按指定的域分隔符劃分。
$1表示第1個域,$n表示第n個域。接着開始讀入第2條記錄.。。直到所有的記錄都讀完,最後執行END操作。
5.搜尋/etc/passwd中含有"root"的所有行:輸出每一行的内容
[[email protected] ~]$ awk '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[[email protected] ~]$ awk -F: '/root/' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
搜尋一行記錄(即不劃分域),可以不用指定域分隔符
6.搜尋/etc/passwd中含有"root"的所有行,并顯示對應的shell
[[email protected] ~]$ awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
/sbin/nologin
[[email protected] ~]$ awk -F ':' '/root/{print $7}' /etc/passwd
/bin/bash
/sbin/nologin
這裡指定了action{print $7}, 另外: -F:和-F ':'效果相同
7.搜尋root開頭的所有行
[[email protected] ~]$ awk '/^root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
AWK常用内置變量
ARGC 指令行參數個數
ARGV 指令行參數排列
ENVIRON 支援隊列中系統環境變量的使用
FILENAME awk浏覽的檔案名
FNR 浏覽檔案的記錄數
FS 設定輸入域分隔符,等價于指令行-F選項
NF 浏覽記錄的域個數
NR 已讀取的記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
RS 控制記錄分隔符
8.統計/etc/passwd:檔案名,每行的行号,每行的列數(域個數),以及對應的完整行内容:
[[email protected] ~]$ awk -F ':' '{print "filename=" FILENAME ",linenumber=" NF ",columns=" NR ",linecontent=" $0}' test0908.txt
filename=test0908.txt,linenumber=2,columns=1,linecontent=1:huangbiquan
filename=test0908.txt,linenumber=2,columns=2,linecontent=2:martin
filename=test0908.txt,linenumber=3,columns=3,linecontent=3:ella:lee
filename=test0908.txt,linenumber=1,columns=4,linecontent=4,bital,peter
filename=test0908.txt,linenumber=3,columns=5,linecontent=5:jane:bital
filename=test0908.txt,linenumber=3,columns=6,linecontent=bital:jamie:jimmy
filename=test0908.txt,linenumber=5,columns=7,linecontent=6:annie:kevin:roy:hunter
可以使用printf代替print:
[[email protected] ~]$ awk -F ':' '{printf("filename=:%10s,linenumber=:%s,columns=:%s,linecontent=:%s\n"),FILENAME,NF,NR,$0}' test0908.txt
filename=:test0908.txt,linenumber=:2,columns=:1,linecontent=:1:huangbiquan
filename=:test0908.txt,linenumber=:2,columns=:2,linecontent=:2:martin
filename=:test0908.txt,linenumber=:3,columns=:3,linecontent=:3:ella:lee
filename=:test0908.txt,linenumber=:1,columns=:4,linecontent=:4,bital,peter
filename=:test0908.txt,linenumber=:3,columns=:5,linecontent=:5:jane:bital
filename=:test0908.txt,linenumber=:3,columns=:6,linecontent=:bital:jamie:jimmy
filename=:test0908.txt,linenumber=:5,columns=:7,linecontent=:6:annie:kevin:roy:hunter
AWK提供兩個列印函數
print: 參數可以是變量、數值或者字元串。其中變量和數值可以直接放在print後面,但是字元串必須要用雙引号,參數間使用逗号分隔(作用和空格相同)
printf: 與C語言中的printf基本相同,可以格式化字元串,輸出複雜時,使用printf更友善.
AWK程式設計: 除了内置變量,還可以自定義變量
9.統計/ect/passwd中賬戶的數量
awk '{i++;print $0;} END {print "User count is "i}' /etc/passwd
[[email protected] ~]$ awk '{i++;print $0;} END {print "User count is "i}' test0908.txt
1:huangbiquan
2:martin
3:ella:lee
4,bital,peter
5:jane:bital
bital:jamie:jimmy
6:annie:kevin:roy:hunter
User count is 7
說明:action{}裡面隻有1個print,action{}可以有多個語句,以;隔開。print是其中一個語句。
[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size/1024/1024,"M"}'
end size is 2.53965 M
10.統計某個檔案夾下檔案占用的位元組數
1)逗号分隔(作用和空格相同)
[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size}'
end size is 2663040
[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is "size}'
end size is 2663040
2)機關改成M
[[email protected] ~]$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END {print "end size is",size/1024/1024,"M"}'
end size is 2.53965 M
注意:這裡的統計部包括檔案夾子目錄
AWK條件語句: 從C語言借鑒過來的
主要有以下三種:
if, if+else, if+else if+else
11.統計某個檔案夾下檔案占用的位元組數,過濾掉位元組數等于4096的檔案
[[email protected]v-l002782 ~]$ ls -l |awk 'BEGIN {size=0;print "start size is",size;} {if($5!=4096){size=size+$5;}} END {print "end size is",size/1024/1024,"M"}'
start size is 0
end size is 2.50501 M
說明:對于{}中的最後一個語句,後面的;可以去掉
AWK中的循環語句: 同樣從C語言借鑒過來的
支援的循環語句有: while, do/while, for, break,continue
12.顯示/etc/passwd檔案中賬戶
awk -F ':' 'BEGIN {i=0;}{name[i]=$1;i++} END {for(i=0; i<NR; i++) print i, name[i]}' /etc/passwd
[[email protected] ~]$ awk -F ':' 'BEGIN {i=0;}{name[i]=$1;i++} END {for(i=0; i<NR; i++) print i, name[i]}' test0908.txt
0 1
1 2
2 3
3 4,bital,peter
4 5
5 bital
6 6