awk命令:
awk也是一個數據處理工具!相較於 sed 常常作用於一整個行的處理, awk 則比較傾向於一行當中分成數個字段來處理。
.awk語言的最基本功能是在文件或字符串中基於指定規則來分解抽取信息,也可以基於指定的規則來輸出數據。
1.命令格式
awk [-F field-separator] 'commands' input-files
其中,[-F域分隔符]是可選的,因爲awk使用空格或tab鍵作爲缺省的域分隔符,因此如果要瀏覽域間有空格的文本,不必指定這個選項,如果要瀏覽諸如passwd文件,此文件各域以冒號作爲分隔符,則必須指明-F選項,如:awk -F: 'commands' input-file。
注:在linux系統中用環境變量IFS存儲分隔符,但根據實際應用也可以改變IFS的值.
例如:
腳本執行結果如下:
commands 是真正awk命令, input-files 是待處理的文件。
iput_files可以是多於一個文件的文件列表,awk將按順序處理列表中的每個文件。
在awk中,文件的每一行中,由域分隔符分開的每一項稱爲一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格或tab鍵。
awk的模式和動作
任何awk語句都由模式和動作組成(awk_pattern { actions })。
在一個awk腳本中可能有許多語句。
模式部分決定動作語句何時觸發及觸發事件。處理即對數據進行的操作。如果省略模式部分,動作將時刻保持執行狀態。即省略時不對輸入記錄進行匹配比較就執行相應的actions。
模式可以是任何條件語句或正則表達式等。awk_pattern可以是以下幾種類型:
1) 正則表達式用作awk_pattern:/regexp/
例如:awk '/^[a-z]/' input_file
2) 布爾表達式用作awk_pattern,表達式成立時,觸發相應的actions執行。
① 表達式中可以使用變量(如字段變量$1,$2等)和/regexp/
② 布爾表達式中的操作符:
關係操作符: <> <= >= == !=
匹配操作符: value ~ /regexp/ 如果value匹配/regexp/,則返回真
value!~ /regexp/ 如果value不匹配/regexp/,則返回真
例如: awk '$2 > 10 {print "ok"}' input_file
awk '$3 ~ /^d/ {print"ok"}' input_file
③ &&(與) 和 ||(或) 可以連接兩個/regexp/或者布爾表達式,構成混合表達式。!(非) 可以用於布爾表達式或者/regexp/之前。
例如: awk '($1< 10 ) && ($2 > 10) {print "ok"}' input_file
awk '/^d/ || /x$/ {print"ok"}' input_file
模式包括兩個特殊字段 BEGIN和END。使用BEGIN語句設置計數和打印頭。BEGIN語句使用在任何文本瀏覽動作之前,之後文本瀏覽動作依據輸入文本開始執行。END語句用來在awk完成文本瀏覽動作後打印輸出文本總數和結尾狀態標誌。
實際動作在大括號{ }內指明。動作大多數用來打印,但是還有些更長的代碼諸如i f和循環語句及循環退出結構。如果不指明採取動作,awk將打印出所有瀏覽出來的記錄。
awk執行時,其瀏覽域標記爲$1,$2...$n。這種方法稱爲域標識。使用這些域標識將更容易對域進行進一步處理。
使用$1 , $3表示參照第1和第3域,注意這裏用逗號做域分隔。如果希望打印一個有5個域
的記錄的所有域,不必指明$1 , $2 , $3 , $4 , $5,可使用$0,意即所有域。
爲打印一個域或所有域,使用print命令。這是一個awk動作
awk的運行過程:
如果BEGIN 區塊存在,awk執行它指定的actions。
awk從輸入文件中讀取一行,稱爲一條輸入記錄。(如果輸入文件省略,將從標準輸入讀取)
awk將讀入的記錄分割成字段,將第1個字段放入變量$1中,第2個字段放入$2,以此類推。$0表示整條記錄。
把當前輸入記錄依次與每一個awk_cmd中awk_pattern比較,看是否匹配,如果相匹配,就執行對應的actions。如果不匹配,就跳過對應的actions,直到比較完所有的awk_cmd。
當一條輸入記錄比較了所有的awk_cmd後,awk讀取輸入的下一行,繼續重複步驟③和④,這個過程一直持續,直到awk讀取到文件尾。
當awk讀完所有的輸入行後,如果存在END,就執行相應的actions。
入門實例:
例1:顯示/etc/passwd文件中的用戶名和登錄shell
如果只是顯示/etc/passwd的賬戶和賬戶對應的shell,而賬戶與shell之間以tab鍵分割
如果只是顯示/etc/passwd文件中的用戶名和登錄shell, 而賬戶與shell之間以逗號分割
注:awk的總是輸出到標準輸出,如果想讓awk輸出到文件,可以使用重定向。
例2:顯示/etc/passwd文件中的UID大於500的所有用戶的用戶名和登錄shell
例3:如果只是顯示/etc/passwd文件中的UID大於500的用戶名和登錄shell,而賬戶與shell之間以逗號分割,而且在所有行添加列名name,shell,在最後一行添加"blue,/bin/nosh"。
注:
1.awk 後面接兩個單引號並加上大括號 {} 來設定想要對數據進行的處理動作
2.awk工作流程是這樣的:先執行BEGING,然後讀取文件,讀入有\n換行符分割的一條記錄,然後將記錄按指定的域分隔符劃分域,填充域,$0則表示所有域,$1表示第一個域,$n表示第n個域,隨後開始執行模式所對應的動作。接着開始讀入第二條記錄······直到所有的記錄都讀完,最後執行END操作。
思考題:如何打印所有記錄(以/etc/passwd中的內容爲例)
例4:搜索/etc/passwd有root關鍵字的所有行
這種是pattern(模式)的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)。
搜索支持正則表達式,例如找root開頭的:
搜索/etc/passwd有root關鍵字的所有行,並顯示對應的shell
這裏指定了action是{print $7}
awk內置變量
awk有許多內置變量用來設置環境信息,下面給出了最常用的一些變量。
FILENAME awk瀏覽的文件名
FS 設置輸入域分隔符,等價於命令行-F選項
NF 瀏覽記錄的域個數(每一行($0)擁有的字段總數)
NR 已讀的記錄數(awk所處理的是第幾行數據)
例5:顯示 /etc/passwd文件中1、3、5、7行對應的完整行內容:
顯示所有賬戶的記錄,並帶有其記錄號,並在END部分打印輸入文件名
除了awk的內置變量,awk還可以自定義變量
例6:統計/etc/passwd的賬戶人數
count是自定義變量。之前的action{}裏都是隻有一個print,其實print只是一個語句,而action{}可以有多個語句,以;號隔開。
這裏沒有初始化count,雖然默認是0,但是妥當的做法還是初始化爲0:
例7:統計某個文件夾下的文件佔用的字節數
如果以M爲單位顯示:
注意:以上統計沒有包括子目錄中的文件。
如果想快速查看所有文件的長度及其總和,但要排除子目錄,如何實現: