歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux強大命令 Awk 20分鐘入門介紹

Linux強大命令 Awk 20分鐘入門介紹

日期:2017/2/28 14:23:08   编辑:Linux教程

什麼是Awk

Awk是一種小巧的編程語言及命令行工具。(其名稱得自於它的創始人Alfred Aho、Peter Weinberger 和 Brian Kernighan姓氏的首個字母)。它非常適合服務器上的日志處理,主要是因為Awk可以對文件進行操作,通常以可讀文本構建行。

我說它適用於服務器是因為日志文件,轉儲文件(dump files),或者任意文本格式的服務器終止轉儲到磁盤都會變得很大,並且在每個服務器你都會擁有大量的這類文件。如果你經歷過這樣的情境——在沒有像Splunk或者其他等價的工具情況下不得不在50個不同的服務器裡分析幾G的文件,你會覺得去獲取和下載所有的這些文件並分析他們是一件很糟糕的事。

我親身經歷過這種情境。當一些Erlang節點將要死掉並留下一個700MB到4GB的崩潰轉儲文件(crash dump)時,或者當我需要在一個小的個人服務器(叫做VPS)上快速浏覽日志,查找一個常規模式時。

在任何情況下,Awk都不僅僅只是用來查找數據的(否則,grep或者ack已經足夠使用了)——它同樣使你能夠處理數據並轉換數據。

--------------------------------------分割線 --------------------------------------

AWK簡介及使用實例 http://www.linuxidc.com/Linux/2013-12/93519.htm

AWK 簡介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htm

Shell腳本之AWK文本編輯器語法 http://www.linuxidc.com/Linux/2013-11/92787.htm

正則表達式中AWK的學習和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm

文本數據處理之AWK 圖解 http://www.linuxidc.com/Linux/2013-09/89589.htm

如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm

文本分析工具-awk http://www.linuxidc.com/Linux/2014-12/110939.htm

--------------------------------------分割線 --------------------------------------

代碼結構

Awk腳本的代碼結構很簡單,就是一系列的模式(pattern)和行為(action):

# comment
Pattern1 { ACTIONS; }

# comment
Pattern2 { ACTIONS; }

# comment
Pattern3 { ACTIONS; }

# comment
Pattern4 { ACTIONS; }

掃描文檔的每一行時都必須與每一個模式進行匹配比較,而且一次只匹配一個模式。那麼,如果我給出一個包含以下內容的文件:

this is line 1

this is line 2

this is line 1 這行就會與Pattern1進行匹配。如果匹配成功,就會執行ACTIONS。然後this is line 1 會和Pattern2進行匹配。如果匹配失敗,它就會跳到Pattern3進行匹配,以此類推。

一旦所有的模式都匹配過了,this is line 2 就會以同樣的步驟進行匹配。其他的行也一樣,直到讀取完整個文件。

簡而言之,這就是Awk的運行模式

數據類型

Awk僅有兩個主要的數據類型:字符串和數字。即便如此,Awk的字符串和數字還可以相互轉換。字符串能夠被解釋為數字並把它的值轉換為數字值。如果字符串不包含數字,它就被轉換為0.

它們都可以在你代碼裡的ACTIONS部分使用 = 操作符給變量賦值。我們可以在任意時刻、任意地方聲明和使用變量,也可以使用未初始化的變量,此時他們的默認值是空字符串:“”。

最後,Awk有數組類型,並且它們是動態的一維關聯數組。它們的語法是這樣的:var[key] = value 。Awk可以模擬多維數組,但無論怎樣,這是一個大的技巧(big hack)。

模式

可以使用的模式分為三大類:正則表達式、布爾表達式和特殊模式。

正則表達式和布爾表達式

你使用的Awk正則表達式比較輕量。它們不是Awk下的PCRE(但是gawk可以支持該庫——這依賴於具體的實現!請使用 awk

–version查看),然而,對於大部分的使用需求已經足夠了:

/admin/ { ... } # any line that contains 'admin'
/^admin/ { ... } # lines that begin with 'admin'
/admin$/ { ... } # lines that end with 'admin'
/^[0-9.]+ / { ... } # lines beginning with series of numbers and periods
/(POST|PUT|DELETE)/ # lines that contain specific HTTP verbs

注意,模式不能捕獲特定的組(groups)使它們在代碼的ACTIONS部分執行。模式是專門匹配內容的。

布爾表達式與PHP或者Javascript中的布爾表達式類似。特別的是,在awk中可以使用&&(“與”)、||(“或”)、!(“非”)操作符。你幾乎可以在所有類C語言中找到它們的蹤跡。它們可以對常規數據進行操作。

與PHP和Javascript更相似的特性是比較操作符,==,它會進行模糊匹配(fuzzy matching)。因此“23”字符串等於23,”23″ == 23 表達式返回true。!= 操作符同樣在awk裡使用,並且別忘了其他常見的操作符:>,<,>=,和<=。

你同樣可以混合使用它們:布爾表達式可以和常規表達式一起使用。 /admin/ || debug == true 這種用法是合法的,並且在遇到包含“admin”單詞的行或者debug變量等於true時該表達式就會匹配成功。

注意,如果你有一個特定的字符串或者變量要與正則表達式進行匹配,~ 和!~ 就是你想要的操作符。 這樣使用它們:string ~ /regex/ 和 string !~ /regex/。

同樣要注意的是,所有的模式都只是可選的。一個包含以下內容的Awk腳本:

{ ACTIONS }

對輸入的每一行都將會簡單地執行ACTIONS。

特殊的模式

在Awk裡有一些特殊的模式,但不是很多。

第一個是BEGIN,它僅在所有的行都輸入到文件之前進行匹配。這是你可以初始化你的腳本變量和所有種類的狀態的主要地方。

另外一個就是END。就像你可能已經猜到的,它會在所有的輸入都被處理完後進行匹配。這使你可以在退出前進行清除工作和一些最後的輸出。

最後一類模式,要把它進行歸類有點困難。它處於變量和特殊值之間,我們通常稱它們為域(Field)。而且名副其實。

使用直觀的例子能更好地解釋域:

# According to the following line
#
# $1 $2 $3
# 00:34:23 GET /foo/bar.html
# _____________ _____________/
# $0

# Hack attempt?
/admin.html$/ && $2 == "DELETE" {
print "Hacker Alert!";
}

域(默認地)由空格分隔。$0 域代表了一整行的字符串。 $1 域是第一塊字符串(在任何空格之前), $2 域是後一塊,以此類推。

一個有趣的事實(並且是在大多是情況下我們要避免的事情),你可以通過給相應的域賦值來修改相應的行。例如,如果你在一個塊裡執行 $0 = “HAHA THE LINE IS GONE”,那麼現在下一個模式將會對修改後的行進行操作而不是操作原始的行。其他的域變量都類似。

行為

這裡有一堆可用的行為(possible actions),但是最常用和最有用的行為(以我的經驗來說)是:

{ print $0; } # prints $0. In this case, equivalent to 'print' alone
{ exit; } # ends the program
{ next; } # skips to the next line of input
{ a=$1; b=$0 } # variable assignment
{ c[$1] = $2 } # variable assignment (array)

{ if (BOOLEAN) { ACTION }
else if (BOOLEAN) { ACTION }
else { ACTION }
}
{ for (i=1; i<x; i++) { ACTION } }
{ for (item in c) { ACTION } }

這些內容將會成為你的Awk工具箱的主要工具,在你處理日志之類的文件時你可以隨意地使用它們。

Awk裡的變量都是全局變量。無論你在給定的塊裡定義什麼變量,它對其他的塊都是可見的,甚至是對每一行都是可見的。這嚴重限制了你的Awk腳本大小,不然他們會造成不可維護的可怕結果。請編寫盡可能小的腳本。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-02/11284p2.htm

Copyright © Linux教程網 All Rights Reserved