AWK簡介

Awk是一種非常通用的編程語言关筒,用于處理文件溶握。我們將只教您足夠的理解這一頁中的例子,再加上一個smidgen蒸播。

為什么學(xué)習(xí)AWK ?

和grep睡榆、sed一樣,AWK是UNIX shell編程的另一個基礎(chǔ)袍榆。
AWK有三種變體:

  1. AWK - the (very old) original from AT&T
  2. NAWK - A newer, improved version from AT&T
  3. GAWK - The Free Software foundation's version

最初胀屿,我不打算討論NAWK,但是一些UNIX供應(yīng)商已經(jīng)用NAWK替換了AWK包雀,而且兩者之間存在一些不兼容之處宿崭。如果我不警告你們這些不同之處,那就太殘忍了才写。所以當(dāng)我講到這些的時候葡兑,我會強(qiáng)調(diào)一下。重要的是要知道赞草,所有AWK的功能都在NAWK和GAWK中讹堤。NAWK的大部分功能(如果不是全部的話)都在GAWK中。NAWK是Solaris的一部分厨疙。GAWK 則不是洲守。然而,Internet上的許多站點(diǎn)都有免費(fèi)的資源沾凄。如果你使用Linux梗醇,你有了GAWK。但一般來說搭独,假設(shè)我說的是經(jīng)典的AWK婴削,除非另有說明。

為什么AWK如此重要?它是一個優(yōu)秀的過濾器和報告編寫器牙肝。許多UNIX程序生成行和列信息。AWK是處理這些行和列的優(yōu)秀工具嗤朴,并且比大多數(shù)傳統(tǒng)編程語言更容易使用AWK配椭。它可以被認(rèn)為是一個偽C解釋器,因?yàn)樗斫馀cC相同的算術(shù)運(yùn)算符雹姊。AWK還具有字符串操作函數(shù)股缸,因此它可以搜索特定的字符串并修改輸出。AWK也有關(guān)聯(lián)數(shù)組吱雏,這是非常有用的敦姻,也是大多數(shù)計(jì)算語言所缺乏的特性瘾境。關(guān)聯(lián)數(shù)組可以使復(fù)雜的問題變得簡單。

我將試著介紹基本的部分或AWK镰惦,并提到擴(kuò)展/變體迷守。“new AWK”或“nawk”出現(xiàn)在太陽系統(tǒng)上旺入,您可能會發(fā)現(xiàn)它在許多方面都優(yōu)于舊AWK兑凿。特別是,它有更好的診斷茵瘾,并且不會打印出原始AWK容易輸出的臭名昭著的“在行附近進(jìn)行救援”消息礼华。相反,“nawk”打印出它不理解的行拗秘,并用箭頭突出顯示不好的部分圣絮。GAWK 也會如此,這真的很有幫助。如果你發(fā)現(xiàn)自己需要一個功能,在AWK是非常困難的或不可能的,我建議你使用NAWK,GAWK,或者使用“a2p”轉(zhuǎn)換程序把你的AWK腳本轉(zhuǎn)換成PERL雕旨。PERL是一種了不起的語言扮匠,我一直在使用它,但是我不打算在這些教程中介紹PERL奸腺。我已經(jīng)表明了我的意圖餐禁,我可以問心無愧地繼續(xù)下去。

許多UNIX實(shí)用程序都有奇怪的名稱突照。AWK就是其中之一帮非。它不是awkward的縮寫。事實(shí)上讹蘑,它是一種優(yōu)雅而簡單的語言末盔。作品“AWK”來源于該語言的三個開發(fā)者的首字母:A. Aho, B. W. Kernighan和P. Weinberger。

基本結(jié)構(gòu)

AWK程序的基本組織形式如下:

pattern { action }

模式(pattern)指定何時執(zhí)行操作座慰。與大多數(shù)UNIX實(shí)用程序一樣陨舱,AWK是面向行的。也就是說版仔,模式指定了一個測試游盲,該測試以每一行讀取為輸入來執(zhí)行。如果條件為真蛮粮,則采取操作益缎。默認(rèn)模式匹配每一行。這是空白或null模式然想。另外兩個重要的模式由關(guān)鍵字“BEGIN”和“END”指定莺奔。如您所料,這兩個詞指定了在讀取任何行之前和讀取最后一行之后要執(zhí)行的操作变泄。AWK程序如下:

BEGIN { print "START" }
      { print         }
END   { print "STOP"  }

在輸入文件之前和之后分別添加一行令哟。這不是很有用恼琼,但通過一個簡單的改變,我們可以把它變成一個典型的AWK程序:

BEGIN { print "File\tOwner"}
{ print $8, "\t", $3}
END { print " - DONE -" }

在下一節(jié)中屏富,我將改進(jìn)這個腳本晴竞,但是我們將它稱為“FileOwner”。但我們先不把它放到腳本或文件中役听。我將稍微介紹一下這部分颓鲜。等一下,跟著我典予,這樣你就能嘗到AWK的味道了甜滨。

字符“\t”表示制表符,因此輸出在偶數(shù)邊界上對齊瘤袖∫履Γ“8”和“3”的含義類似于shell腳本。不是第8和第3個參數(shù)捂敌,而是輸入行的第8和第3個字段艾扮。您可以將字段視為一列,您指定的操作對每一行列進(jìn)行操作占婉。

AWK和處理雙引號內(nèi)字符的shell之間有兩個不同之處泡嘴。AWK可以理解像“t”這樣跟在“\”字符后面的特殊字符。Bourne和C UNIX shell則不理解逆济。另外酌予,與shell(和PERL)不同,AWK不計(jì)算字符串中的變量奖慌。為了解釋抛虫,第二行不能這樣寫:

{print "$8\t$3" }

該示例將打印“83”。在引號內(nèi)简僧,$符號不是一個特殊字符建椰。在外部,它對應(yīng)一個字段岛马。我說的第三和第八個字段是什么意思?考慮Solaris“/usr/bin/ls -l”命令棉姐,它有8列信息。System V版本(類似于Linux版本)啦逆,“/usr/5bin/ls -l”有9列谅海。第三列是所有者,第八列(或第九列)是文件名稱蹦浦。這個AWK程序可以用來處理“l(fā)s -l”命令的輸出,打印出每個文件的文件名撞蜂,然后是所有者盲镶。我來教你怎么做侥袜。

更新:在linux系統(tǒng)上,將“8”更改為“9”溉贿。

關(guān)于使用符號還有一點(diǎn)枫吧。在Perl等腳本語言和各種shell中,符號表示接下來的單詞是變量的名稱宇色。Awk是不同的九杂。符號表示我們正在引用當(dāng)前行中的字段或列。在Perl和AWK之間切換時宣蠕,必須記住“”有不同的含義例隆。因此,下面的代碼將打印兩個“字段”以進(jìn)行標(biāo)準(zhǔn)輸出抢蚀。打印的第一個字段是數(shù)字“5”镀层,第二個字段是輸入行上的第五個字段(或列)。

BEGIN { x=5 }
{ print x, $x}

執(zhí)行AWK腳本

讓我們開始編寫第一個AWK腳本皿曲。有幾種方法可以做到這一點(diǎn)唱逢。

假設(shè)第一個腳本名為“FileOwner”,那么調(diào)用將是

ls -l | FileOwner

如果當(dāng)前目錄中只有兩個文件屋休,則可能生成以下內(nèi)容:

File    Owner

a.file  barnett
another.file barnett
- DONE -

這個腳本有兩個問題坞古。這兩個問題都很容易解決,但是我將在介紹基本知識之前暫時不討論這個問題劫樟。

腳本本身可以用多種方式編寫痪枫。我已經(jīng)展示了C shell (csh/tcsh)和Bourne/Bash/POSIX shell腳本。C shell版本應(yīng)該是這樣的:

#!/bin/csh -f
# Linux users have to change $8 to $9
awk '\
BEGIN   { print "File\tOwner" } \
        { print $8, "\t", $3}   \
END     { print " - DONE -" } \
'

當(dāng)然毅哗,一旦您創(chuàng)建了這個腳本听怕,您需要使這個腳本可執(zhí)行:

chmod +x awk_example.1.csh

test:

ls -l | sh FileOwner

正如您在上面的腳本中看到的,如果不是腳本的最后一行虑绵,AWK腳本的每一行都必須有一個反斜杠尿瞭。這是必要的,因?yàn)槟J(rèn)情況下翅睛,C shell不允許字符串超過一行声搁。我有一長串關(guān)于使用C shell的抱怨。

Bourne shell(和大多數(shù)shell一樣)允許引用字符串跨越幾行:

!/bin/sh
# Linux users have to change $8 to $9 
awk '
BEGIN { print "File\tOwner" } 
{ print $8, "\t", $3}   
END { print " - DONE -" } 

再次說明捕发,一旦它被創(chuàng)建疏旨,它必須是可執(zhí)行的:

chmod +x awk_example1.sh

順便說一下,我在教程中給出了示例腳本扎酷,并在文件名上使用擴(kuò)展名來指示腳本的類型檐涝。當(dāng)然,您可以通過輸入以下代碼把腳本“install”到您的home“bin”目錄中:

cp awk_example1.sh $HOME/bin/awk_example1
chmod +x $HOME/bin/awk_example1

第三種類型的AWK腳本是“原生的”AWK腳本,其中不使用shell谁榜。您可以在文件中編寫命令并執(zhí)行:

awk -f filename

因?yàn)锳WK也是一個解釋器幅聘,就像shell一樣,你可以節(jié)省一個步驟窃植,在文件的開頭添加一行代碼帝蒿,使文件可執(zhí)行:

#!/bin/awk -f
BEGIN { print "File\tOwner" }
{ print $8, "\t", $3}
END { print " - DONE -" }

然后執(zhí)行“chmod +x”并將此文件作為一個新的UNIX命令進(jìn)行ise。

注意“#!/bin/awk”后面的“-f”選項(xiàng)巷怜,它也用于第三種格式葛超,在這種格式中,您使用AWK直接執(zhí)行文件延塑,即“awk - f文件名”绣张。“-f”選項(xiàng)指定包含指令的AWK文件页畦。如您所見胖替,AWK將以“#”開頭的行視為注釋,就像shell一樣豫缨。準(zhǔn)確地說独令,從“#”到行尾的任何內(nèi)容都是注釋(除非它在AWK字符串中)。但是好芭,我總是在行首用“#”來注釋AWK腳本燃箭,原因我將在后面討論。

應(yīng)該使用哪種格式?如果可能的話舍败,我更喜歡最后一種格式招狸。它更短更簡單。調(diào)試問題也更容易邻薯。如果您需要使用shell裙戏,并且希望避免使用太多的文件,您可以像我們在第一個和第二個示例中所做的那樣組合它們厕诡。

用哪種shell搭配AWK?

原始AWK的格式不是自由格式的累榜。你不能把換行符放在任何地方。他們必須去特定的地方灵嫌。確切地說壹罚,在最初的AWK中,您可以在大括號后面和命令末尾插入一個新行字符寿羞,但不能在其他地方插入猖凛。如果你想在任何地方把一條長線分成兩行,你必須使用反斜杠(awk_example2.awk):

#!/bin/awk -f
BEGIN { print "File\tOwner" }
{ print $8, "\t", \ 
$3} 
END { print " - DONE -" }

Bourne shell版本是( awk_example2.sh):

#!/bin/sh
awk '
BEGIN   { print "File\tOwner" }
{ print $8, "\t", \
$3}
END { print "done"} 
'

C shell版本是( awk_example2.csh):

#!/bin/csh -f
awk '
BEGIN   { print "File\tOwner" }\
{ print $8, "\t", \\
$3}\
END { print "done"}\
'

正如您所看到的绪穆,這演示了C shell在封裝AWK腳本時是多么笨拙辨泳。不僅每一行都需要反斜杠虱岂,有些行需要兩個斜杠,然后使用原來的AWK漠吻。更新的AWK更靈活量瓜,可以添加新行。
很多人途乃,像我一樣,會警告你注意C shell扔傅。有些問題很微妙耍共,你可能永遠(yuǎn)也看不到。嘗試在C shell腳本中包含AWK或sed腳本猎塞,而反斜杠會讓您發(fā)瘋试读。這就是多年前說服我學(xué)習(xí)Bourne shell的原因,當(dāng)時我剛開始學(xué)習(xí)(在Korn shell或Bash shell可用之前)荠耽。即使您堅(jiān)持使用C shell钩骇,至少也應(yīng)該學(xué)習(xí)足夠多的Borne/POSIX shell來設(shè)置變量,由于某種奇怪的巧合铝量,這將是下一節(jié)的主題倘屹。

動態(tài)變量

因?yàn)槟梢酝ㄟ^把"#!/bin/awk -f"寫在第一行中使腳本可執(zhí)行,所以不需要在shell腳本中包含AWK腳本慢叨,除非您希望消除對額外文件的需要纽匙,或者希望將變量傳遞到AWK腳本的內(nèi)部。由于這是一個常見的問題拍谐,現(xiàn)在正是解釋該技術(shù)的好時機(jī)烛缔。我將通過顯示一個只打印一列的簡單AWK程序來實(shí)現(xiàn)這一點(diǎn)。注意:第一個版本會有一個bug轩拨。 列的數(shù)目將由第一個參數(shù)指定践瓷。程序的第一個版本的名字我們稱之為“列”,看起來是這樣的:

#!/bin/sh
#NOTE - this script does not work!
column=$1
awk '{print $column}'

建議的用法是:

ls -l | Column 3

未完待續(xù)...

鏈接

http://www.grymoire.com/Unix/Awk.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亡蓉,一起剝皮案震驚了整個濱河市晕翠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寸宵,老刑警劉巖崖面,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梯影,居然都是意外死亡巫员,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門甲棍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來简识,“玉大人,你說我怎么就攤上這事∑呷牛” “怎么了奢赂?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颈走。 經(jīng)常有香客問我膳灶,道長,這世上最難降的妖魔是什么立由? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任轧钓,我火速辦了婚禮,結(jié)果婚禮上锐膜,老公的妹妹穿的比我還像新娘毕箍。我一直安慰自己,他們只是感情好道盏,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布而柑。 她就那樣靜靜地躺著,像睡著了一般荷逞。 火紅的嫁衣襯著肌膚如雪媒咳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天颅围,我揣著相機(jī)與錄音伟葫,去河邊找鬼。 笑死院促,一個胖子當(dāng)著我的面吹牛筏养,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播常拓,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼渐溶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弄抬?” 一聲冷哼從身側(cè)響起咧欣,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤娶桦,失蹤者是張志新(化名)和其女友劉穎昼激,沒想到半個月后障本,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懊亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年依啰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片店枣。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡速警,死狀恐怖叹誉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闷旧,我是刑警寧澤长豁,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站忙灼,受9級特大地震影響匠襟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缀棍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一宅此、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爬范,春花似錦、人聲如沸弱匪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萧诫。三九已至斥难,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帘饶,已是汗流浹背哑诊。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留及刻,地道東北人镀裤。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像缴饭,于是被迫代替她去往敵國和親暑劝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一颗搂、systemd的新特性及unit常見類型 systemd即為system daemon担猛,是Centos 7上用...
    煙雨江南_e5eb閱讀 1,089評論 0 0
  • 轉(zhuǎn)載 原文的排版和內(nèi)容都更加友好,并且詳細(xì),我只是在這里貼出了一部分留作自己以后參考和學(xué)習(xí),如希望更詳細(xì)了解AWK...
    XKirk閱讀 3,188評論 2 25
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 5,720評論 0 10
  • 本文參考awk英文Tutorial和三十分鐘學(xué)會awk[https://github.com/mylxsw/gro...
    蜘蛛魚閱讀 314評論 0 0
  • 一. AWK 說明 awk的處理文本和數(shù)據(jù)的方式:它逐行掃描文件丢氢,從第一行到最后一行傅联,尋找匹配的特定模式的行,并...
    西華子閱讀 923評論 0 4