linux awk详解
1.字段的理解
awk是一個(gè)強(qiáng)大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數(shù)據(jù)分析并生成報(bào)告時(shí),顯得尤為強(qiáng)大。簡單來說awk就是把文件逐行的讀入,以空格為默認(rèn)分隔符將每行切片,切開的部分再進(jìn)行各種分析處理。
在學(xué)習(xí)之前先熟悉一個(gè)字段:/etc/passwd中的字段
/etc/passwd中,每行包含7個(gè)字段(從1開始數(shù)共7個(gè)),他們分別代表:用戶名:密碼:用戶ID:組ID:描述:主目錄:默認(rèn)shell
第二個(gè)字段就是密碼,一般加密后放在/etc/shadow里;
具體的詳細(xì)信息如下:
1)“用戶名”是代表用戶賬號的字符串。通常長度不超過8個(gè)字符,并且由大小寫字母和/或數(shù)字組成。登錄名中不能有冒號(,因?yàn)槊疤栐谶@里是分隔符。為了兼容起見,登錄名中最好不要包含點(diǎn)字符(.),并且不使用連字符(-)和加號(+)打頭。
2)“口令”一些系統(tǒng)中,存放著加密后的用戶口令字。。雖然這個(gè)字段存放的只是用戶口令的加密串,不是
明文,但是由于/etc/passwd文件對所有用戶都可讀,所以這仍是一個(gè)安全隱患。因此,現(xiàn)在許多 Linux
系統(tǒng)(如SVR4)都使用了shadow技術(shù),把真正的加密后的用戶口令字存放到/etc/shadow文件中,而在/etc/passwd文件的口令字
段中只存放一個(gè)特殊的字符,例如“x”或者“*”。
3)“用戶標(biāo)識號”是一個(gè)整數(shù),系統(tǒng)內(nèi)部用它來標(biāo)識用戶。一般情況下它與用戶名是一一對應(yīng)的。如果幾個(gè)用戶名對應(yīng)的用戶標(biāo)識號是一樣的,系統(tǒng)內(nèi)部將把它們視為同一個(gè)用戶,但是它們可以有不同的口令、不同的主目錄以及不同的登錄Shell等。
通常用戶標(biāo)識號的取值范圍是0~65 535。0是超級用戶root的標(biāo)識號,1~99由系統(tǒng)保留,作為管理賬號,普通用戶的標(biāo)識號從100開始。在Linux系統(tǒng)中,這個(gè)界限是500。
4)“組標(biāo)識號”字段記錄的是用戶所屬的用戶組。它對應(yīng)著/etc/group文件中的一條記錄。
5)“注釋性描述”字段記錄著用戶的一些個(gè)人情況,例如用戶的真實(shí)姓名、電話、地址等,這個(gè)字段并沒有什么實(shí)際的用途。在不同的Linux
系統(tǒng)中,這個(gè)字段的格式并沒有統(tǒng)一。在許多Linux系統(tǒng)中,這個(gè)字段存放的是一段任意的注釋性描述文字,用做finger命令的輸出。
6)“主目錄”,也就是用戶的起始工作目錄,它是用戶在登錄到系統(tǒng)之后所處的目錄。在大多數(shù)系統(tǒng)中,各用戶的主目錄都被組織在同一個(gè)特定的目錄下,而
用戶主目錄的名稱就是該用戶的登錄名。各用戶對自己的主目錄有讀、寫、執(zhí)行(搜索)權(quán)限,其他用戶對此目錄的訪問權(quán)限則根據(jù)具體情況設(shè)置。
7)用戶登錄后,要啟動一個(gè)進(jìn)程,負(fù)責(zé)將用戶的操作傳給內(nèi)核,這個(gè)進(jìn)程是用戶登錄到系統(tǒng)后運(yùn)行的命令解釋器或某個(gè)特定的程序,即Shell。
Shell 是用戶與Linux系統(tǒng)之間的接口。Linux的Shell有許多種,每種都有不同的特點(diǎn)。常用的有sh(Bourne Shell),
csh(C Shell), ksh(Korn Shell), tcsh(TENEX/TOPS-20 type C Shell),
bash(Bourne Again
Shell)等。系統(tǒng)管理員可以根據(jù)系統(tǒng)情況和用戶習(xí)慣為用戶指定某個(gè)Shell。如果不指定Shell,那么系統(tǒng)使用sh為默認(rèn)的登錄Shell,即這個(gè)字段的值為/bin/sh。
用戶的登錄Shell也可以指定為某個(gè)特定的程序(此程序不是一個(gè)命令解釋器)。利用這一特點(diǎn),我們可以限制用戶只能運(yùn)行指定的應(yīng)用程序,在該應(yīng)用程序運(yùn)行結(jié)束后,用戶就自動退出了系統(tǒng)。有些Linux 系統(tǒng)要求只有那些在系統(tǒng)中登記了的程序才能出現(xiàn)在這個(gè)字段中。
cat /etc/group
組名:加密密碼:組ID:所有屬于該組的用戶。
在對/etc/passwd 和/etc/passwd字段中的內(nèi)容了解了之后,進(jìn)入主題:
2.入門實(shí)例
awk ‘{pattern + action}’ {filenames}
其中 pattern 表示 AWK 在數(shù)據(jù)中查找的內(nèi)容,一個(gè)Pattern是一個(gè)正則表達(dá)式經(jīng)編譯后的表現(xiàn)模式。而 action 是在找到匹配內(nèi)容時(shí)所執(zhí)行的一系列命令。花括號({})不需要在程序中始終出現(xiàn),但它們用于根據(jù)特定的模式對一系列指令進(jìn)行分組。 pattern就是要表示的正則表達(dá)式,用斜杠括起來。
注:awk語言的最基本功能是在文件或者字符串中基于指定規(guī)則瀏覽和抽取信息,awk抽取信息后,才能進(jìn)行其他文本操作。完整的awk腳本通常用來格式化文本文件中的信息。通常,awk是以文件的一行為處理單位的。awk每接收文件的一行,然后執(zhí)行相應(yīng)的命令,來處理文本。
#awk -F: ‘/root/’ /etc/passwd
這種是pattern的使用示例,匹配了pattern(這里是root)的行才會執(zhí)行action(沒有指定action,默認(rèn)輸出每行的內(nèi)容)。
搜索支持正則,例如找root開頭的:
awk -F: ‘/^root/’ /etc/passwd
搜索/etc/passwd有root關(guān)鍵字的所有行,并顯示對應(yīng)的shell
如果只是顯示/etc/passwd的賬戶和賬戶對應(yīng)的shell,而賬戶與shell之間以tab鍵分割:
另外的:
假設(shè)last -n 5的輸出如下:
如果只是顯示最近登錄的5個(gè)帳號
如果只是顯示/etc/passwd的賬戶和賬戶對應(yīng)的shell,而賬戶與shell之間以逗號分割,而且在所有行添加列名name,shell,在最后一行添加”blue,/bin/nosh”。
awk工作流程是這樣的:先執(zhí)行BEGING,然后讀取文件,讀入有/n換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域,0則表示所有域,1表示第一個(gè)域,$n表示第n個(gè)域,隨后開始執(zhí)行模式所對應(yīng)的動作action。接著開始讀入第二條記錄······直到所有的記錄都讀完,最后執(zhí)行END操作。
3.awk內(nèi)置變量
ARGC 命令行參數(shù)個(gè)數(shù) ARGV 命令行參數(shù)排列 ENVIRON 支持隊(duì)列中系統(tǒng)環(huán)境變量的使用 FILENAME awk瀏覽的文件名 FNR 瀏覽文件的記錄數(shù) FS 設(shè)置輸入域分隔符,等價(jià)于命令行 -F選項(xiàng) NF 瀏覽記錄的域的個(gè)數(shù) NR 已讀的記錄數(shù) OFS 輸出域分隔符 ORS 輸出記錄分隔符 RS 控制記錄分隔符統(tǒng)計(jì)/etc/passwd:文件名,每行的行號,每行的列數(shù),對應(yīng)的完整行內(nèi)容:
使用printf替代print,可以讓代碼更加簡潔,易讀
awk -F ‘:’ ‘{printf(“filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n”,FILENAME,NR,NF,$0)}’ /etc/passwd
下面做個(gè)awk 內(nèi)置變量 NF NR的小實(shí)驗(yàn):
1)NF:
grep “Failed” /var/log/secure:
grep “Failed” /var/log/secure | awk ‘{print $(NF-3)}’:
NF-3的意思是倒數(shù)第三個(gè)字段,ssh2是第-0個(gè)字段,663951是第-1個(gè)字段….192.168.33.20是第-3個(gè)字段。
同理# grep “Failed” /var/log/secure | awk ‘{print $(NF-9)}’結(jié)果為:
它和# grep “Failed” /var/log/secure | awk ‘{print $(5)}’命令結(jié)果是一樣的:
上面的例子是NF,也就是NF,如果是NF就不同了,NF就代表被(默認(rèn))空格分開的域的個(gè)數(shù):
2)NR:
NR代表執(zhí)行的行數(shù):也就是假如bbb.log的文本有如下內(nèi)容:
111b
222b
那么:grep “1” bbb.log | awk ‘{print NR}’
就會返回:1
那么:grep “2” bbb.log | awk ‘{print NR}’
就會返回:2
那么:grep “b” bbb.log | awk ‘{print NR}’
就會返回:
1
2
假設(shè)bbb.log的文本有如下內(nèi)容:
111b
222b
333c
444d
555b
grep “b” bbb.log | awk ‘{print NR}’
返回:
1
2
3
為什么是1 2 3 而不是1 2 5 不是行數(shù)么?
因?yàn)間rep “b” bbb.log的結(jié)果是:
111b
222b
555b
然后這個(gè)結(jié)果管道給awk的,所以1 2 3。
4.awk編程
變量和賦值
除了awk的內(nèi)置變量,awk還可以自定義變量。
下面統(tǒng)計(jì)/etc/passwd的賬戶人數(shù)
awk ‘{count++;print $0;} END{print “user count is “, count}’ /etc/passwd
count是自定義變量。之前的action{}里都是只有一個(gè)print,其實(shí)print只是一個(gè)語句,而action{}可以有多個(gè)語句,以;號隔開。
這里沒有初始化count,雖然默認(rèn)是0,但是妥當(dāng)?shù)淖龇ㄟ€是初始化為0:
awk ‘BEGIN {count=0;print “[start]user count is “, count} {count=count+1;print $0;} END{print “[end]user count is “, count}’ /etc/passwd
統(tǒng)計(jì)某個(gè)文件夾下的文件占用的字節(jié)數(shù):
ls -l |awk ‘BEGIN {size=0;} {size=size+$5;} END{print “[end]size is “, size}’
如果以M為單位顯示:
ls -l |awk ‘BEGIN {size=0;} {size=size+$5;} END{print “[end]size is “, size/1024/1024,”M”}’
條件語句
awk中的條件語句是從C語言中借鑒來的,見如下聲明方式:
例如,統(tǒng)計(jì)某個(gè)文件夾下的文件占用的字節(jié)數(shù),過濾4096大小的文件(一般都是文件夾):
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”}’
循環(huán)語句
awk中的循環(huán)語句同樣借鑒于C語言,支持while、do/while、for、break、continue,這些關(guān)鍵字的語義和C語言中的語義完全相同。
數(shù)組
因?yàn)閍wk中數(shù)組的下標(biāo)可以是數(shù)字和字母,數(shù)組的下標(biāo)通常被稱為關(guān)鍵字(key)。值和關(guān)鍵字都存儲在內(nèi)部的一張針對key/value應(yīng)用hash的表格里。由于hash不是順序存儲,因此在顯示數(shù)組內(nèi)容時(shí)會發(fā)現(xiàn),它們并不是按照你預(yù)料的順序顯示出來的。數(shù)組和變量一樣,都是在使用時(shí)自動創(chuàng)建的,awk也同樣會自動判斷其存儲的是數(shù)字還是字符串。一般而言,awk中的數(shù)組用來從記錄中收集信息,可以用于計(jì)算總和、統(tǒng)計(jì)單詞以及跟蹤模板被匹配的次數(shù)等等。
下面使用for循環(huán)遍歷數(shù)組,顯示/etc/passwd的賬戶:
awk -F ‘:’ ‘BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}’ /etc/passwd
awk編程的內(nèi)容極多,這里只羅列簡單常用的用法,更多請參考 http://www.gnu.org/software/gawk/manual/gawk.html
總結(jié)
以上是生活随笔為你收集整理的linux awk详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: onclick函数的导包问题
- 下一篇: linux ps