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