Awk 是一個維護和處理文本數據文件的強大語言。在文本數據有一定的格式,即每行數據包 含多個以分界符分隔的字段時,顯得尤其有用。 即便是輸入文件沒有一定的格式,你仍然可 以使用 awk 進行基本的處理。 Awk 當然也可以沒有輸入文件,那不是必須的。 簡言之, AWK 是一種能處理從瑣碎的小事到日常例行公事的強大語言。
1.基礎語法:
awk [-F field-separator] '/pattern/ {action}' input-file (或者) awk [-F field-separator] '{action}' input-file
上面語法中:
-F 為字段分界符。如果不指定,默認會使用空格作為分界符。
/pattern/和{action}需要用單引號引起來。
/pattern/是可選的。如果不指定, awk 將處理輸入文件中的所有記錄。如果指定一個模式, awk 則只處理匹配指定的模式的記錄。
{action} 為 awk 命令,可以是單個命令,也可以多個命令。整個 action(包括裡面的所有命令)都必須放在{ 和 }之間。
Input-file 即為要處理的文件
實例1:打印/etc/passwd文件中mail用戶所在行的用戶名mail
[root@localhost ~]# grep '^mail' /etc/passwd mail:x:8:12:mail:/var/spool/mail:/sbin/nologin [root@localhost ~]# awk -F: '/mail/{print $1}' /etc/passwd #-F ":"也是正確的 mail
2.awk腳本:
當需要執行很多 awk 命令時, 可以把/pattern/{action}這一部分放到單獨的文件中,然後調 用它:
awk –Fs –f myscript.awk input-file #[-F field-separator]簡寫 -FS
也可以在這個文件中設置字段分界符(後面詳述),然後調用:
awk –f myscript.awk input-file
1.BEGIN 區域
Begin 區域的語法:
BEGIN { awk-commands }
說明:BEGIN 區域的命令只最開始、在 awk 執行 body 區域命令之前執行一次。
BEGIN 區域很適合用來打印報文頭部信息,以及用來初始化變量。
BEGIN 區域可以有一個或多個 awk 命令
關鍵字 BEGIN 必須要用大寫
BEGIN 區域是可選的
2.body 區域
body 區域的語法:
/pattern/ {action}
body 區域的命令每次從輸入文件讀取一行就會執行一次
如果輸入文件有 10 行,那 body 區域的命令就會執行 10 次(每行執行一次)
Body 區域沒有用任何關鍵字表示,只有用正則模式和命令。
3.END block
END 區域的語法:
END { awk-commands }
END 區域在 awk 執行完所有操作後執行,並且只執行一次。
END 區域很適合打印報文結尾信息,以及做一些清理動作
END 區域可以有一個或多個 awk 命令
關鍵字 END 必須要用大寫
END 區域是可選的
awk執行流程圖:
實例1:
[root@localhost ~]# awk ' > BEGIN{FS=":";print "----header----"} #打印內容字符串要用雙引號,單引號有語法錯誤 > /mail/{print $1} > END{print "----footer----"} > ' /etc/passwd ----header---- mail ----footer----
提示:如果命令很長,即可以放到單行執行,也可以用\折成多行執行。
實例2:通過awk腳本執行實例1中的命令
[root@localhost ~]# cat myscript.awk BEGIN{ FS=":" print "----header----" } /mail/{ print $1 } END{ print "----footer----" } [root@localhost ~]# awk -f myscript.awk /etc/passwd ----header---- mail ----footer----
說明:awk 腳本中,注釋以#開頭。
只使用 BEGIN 區域在 awk 中是符合語法的。在沒有使用 body 區域時,不需要指定輸入文件, 因為 body 區域只在輸入文件上執行。 所以在執行和輸入文件無關的工作時,可以只使用 BEGIN 區域。
實例3:只使用BEGIN無輸入文件
[root@localhost ~]# awk 'BEGIN{print "HELLO WORLD"}' HELLO WORLD
4.多個輸入文件:
awk 指定多個輸入文件。如果指定了兩個文件,那麼 body 區域會首先在第一 個文件的所有行上執行,然後在第二個文件的所有行上執行。
實例4:多文件處理
[root@localhost ~]# awk -F: ' > BEGIN{print "----header----"} > /mail/{print $1} > END{print "----footer----"} > ' /etc/passwd /etc/group ----header---- mail mail ----footer----
注意:即是指定了多個文件, BEGIN 和 END 區域,仍然只會執行一次。
默認情況下,awk 的打印命令 print(不帶任何參數)會打印整行數據。下面的例子等價於”cat employee.txt”命令。
實例1:不帶參數
[root@localhost ~]# awk '{print}' emp 101,John Doe,CEO 102,Jason Smith,IT Manager 103,Raj Reddy,Sysadmin 104,Anand Ram,Developer 105,Jane Miller,Sales Manager
實例2:也可以通過傳遞變量”$字段序號”作為 print 的參數來指定要打印的字段。
[root@localhost ~]# awk '{print $2}' ./emp #默認以空格為分隔符 Doe,CEO Smith,IT Reddy,Sysadmin Ram,Developer Miller,Sales
實例3:輸出雇員姓名與職位
[root@localhost ~]# cat emp 101,John Doe,CEO 102,Jason Smith,IT Manager 103,Raj Reddy,Sysadmin 104,Anand Ram,Developer 105,Jane Miller,Sales Manager [root@localhost ~]# awk ' >BEGIN{FS=",";print "-------\nNAME Title\n--------\n"} >{print $2,"\t",$3} #打印多變量,之間用逗號或者空格分隔 >END{print "----------------"}' emp ------- NAME Title -------- John Doe CEO Jason Smith IT Manager Raj Reddy Sysadmin Anand Ram Developer Jane Miller Sales Manager ----------------
說明:請注意, $0 代表整條記錄。 下面兩個命令是等價的,都打印 employee.txt 的所有行:
awk '{print}' emp awk '{print $0}' emp
只在匹配特殊模式的行數執行 awk 命令。
實例1:只處理匹配行
[root@localhost ~]# awk -F, '/Manager/{print $2,$3}' emp Jason Smith IT Manager Jane Miller Sales Manager
實例2:只打印雇員 id 為 102 的雇員的信息
[root@localhost ~]# awk -F, '/^102/{print "Emp is 102 is",$2}' emp Emp is 102 is Jason Smith