AWK 作為*uix下的一款優(yōu)秀的工具,在文本處理方面擁有天然的優(yōu)勢(shì)。此文是我本周業(yè)余時(shí)間學(xué)習(xí)、整理而成。作為一名程序新手,對(duì)這款上古神器難免有理解不到的地方,不正確之處,勞煩斧正。
前情提要
本文將使用歌曲Color Blind的歌詞作為AWK待處理的文本源,原因其一是我最近成功的被樓下理發(fā)店的這首歌洗腦;其二就是歌詞比較有特點(diǎn),適合用來(lái)說(shuō)明AWK的用法。你可以在點(diǎn)擊這里下載我整理過(guò)后的歌詞:ColorBlind.txt
劇情鋪墊
想要了解一個(gè)命令,首先需要知道它的一些約定俗成的規(guī)定。這就是*nix中命令強(qiáng)大的部分原因,你可以一步一步的告訴我怎么做,也可以簡(jiǎn)明扼要,我會(huì)有默認(rèn)的、最貼近大眾化需求的處理方法。
以下是AWK的一些默認(rèn)規(guī)則:
AWK會(huì)默認(rèn)通過(guò)循環(huán)處理輸入文件的每一行
AWK 會(huì)默認(rèn)打印處理后的結(jié)果
AWK 指令由模式、操作、或模式與操作的組合組成。簡(jiǎn)潔表示為
pattern { action },其中,操作需要用大括號(hào)括起來(lái),模式默認(rèn)暗含if關(guān)鍵字,常見(jiàn)用法是通過(guò)模式選擇需要處理的行,在操作中進(jìn)行處理。AWK包含BEGIN與END兩種特殊模式,每個(gè)模式后緊跟由大括號(hào)括起來(lái)的操作塊,BEGIN對(duì)應(yīng)的操作快是對(duì)輸入文件進(jìn)行處理之前先執(zhí)行,END則是最后。
-
AWK包含了一些關(guān)鍵字,這些關(guān)鍵字中記錄著常用信息,可以在操作中引用這些關(guān)鍵字。
$0 存放著當(dāng)前處理行的所有內(nèi)容 $1~$n 當(dāng)前記錄的第n個(gè)字段,字段間由FS分隔 FS 輸入字段分隔符 默認(rèn)是空格或Tab NF 當(dāng)前記錄中的字段個(gè)數(shù),就是有多少列 NR 已經(jīng)讀出的行號(hào),從1開始,如果有多個(gè)文件話,這個(gè)值也是不斷累加中。 FNR 當(dāng)前行數(shù),與NR不同的是,這個(gè)值會(huì)是各個(gè)文件自己的行號(hào) FILENAME 當(dāng)前輸入文件的名字
單純的文字畢竟會(huì)枯燥,不過(guò)有了上面的這些基礎(chǔ),我們可以進(jìn)入AWK這幕大劇了。
劇情深入
-
完整輸出文件
AWK默認(rèn)循環(huán)處理,$0代表當(dāng)前行,默認(rèn)打印,因此打印輸出文件很簡(jiǎn)單:
awk '$0' ColorBlind.txt上面使用了默認(rèn)選中的結(jié)果會(huì)被默認(rèn)打印的特性,當(dāng)然我們可以使用操作將其打印出來(lái):
awk '{ print $0 }' ColorBlind.txt 輸出行數(shù)
對(duì)于單個(gè)文件,F(xiàn)NR記錄著行數(shù)信息,所以我們?cè)贓ND模式中對(duì)其輸出即可知道文件的行數(shù):
awk 'END{ print FNR }' ColorBlind.txt
-
輸出單詞個(gè)數(shù)
AWK中變量無(wú)需聲明即可直接使用,NF記錄著當(dāng)前行的列數(shù),即單詞數(shù)量,所以將其相加即可:
awk '{ x+=NF } END { print x}' ColorBlind.txt -
去除重復(fù)行
AWK 是有數(shù)組的概念的,因此這也不難
awk '{ if ( !line[$0] ) print $0; line[$0]++ }' ColorBlind.txt -
輸出大于20個(gè)字符的行
length關(guān)鍵字表示當(dāng)前行的字符數(shù),因此這個(gè)需求很簡(jiǎn)單
awk 'length > 20 ' ColorBlind.txt -
輸出
black & white歌詞出現(xiàn)次數(shù)前面說(shuō)過(guò),AWK 模式默認(rèn)隱含if關(guān)鍵字,同時(shí),模式也可以是用兩個(gè)
/包裹的正則表達(dá)式,表示是否成功匹配當(dāng)前行awk '/black & white/ {x++} END{print x}' ColorBlind.txt
高潮
AWK的技巧可不僅如此,我們玩一些更復(fù)雜的。
- 生成隨機(jī)數(shù)
AWK內(nèi)置了一些函數(shù),比如rand是用來(lái)生成隨機(jī)數(shù)的,我想生成10個(gè)隨機(jī)數(shù)可以這樣:
yes | head -10 | awk '{print rand()}'
- 批量備份
假設(shè)ColorBlind這首歌的歌詞創(chuàng)作者從初稿到終稿經(jīng)過(guò)了n多個(gè)版本,命名大致如下:
ColorBlind1.txt
ColorBlind2.txt
ColorBlind3.txt
ColorBlind4.txt
ColorBlind_don't_change.txt
....
ColorBlind_nerver.txt
ColorBlind_last_change.txt
ColorBlind_fu*k.txt
ColorBlind_dead.txt
作者想將其備份到路徑/color/backup/目錄下,并且每個(gè)文件需要添加.dat后綴表示為備份文件,即ColorBlind1.txt->ColorBlind1.txt.dat
通過(guò)AWK來(lái)實(shí)現(xiàn)的思路可以是根據(jù)文件名稱組裝mv命令,然后通過(guò)csh來(lái)執(zhí)行
ls ColorBlind* | awk '{print "mv "$0" /color/backup/"$0".dat"}' | csh
- 復(fù)雜命令
其實(shí)AWK命令可以寫的很復(fù)雜,通常一行命令可能不會(huì)滿足需求,所以AWK同時(shí)也提供了從文件讀取命令的方式,甚至可以自定義函數(shù),這里不做過(guò)多介紹, 因?yàn)檫^(guò)于復(fù)雜的邏輯通過(guò)bash
、python之類也未嘗不可。選擇什么只是業(yè)務(wù)需要與便捷之間的權(quán)衡。
結(jié)局
文章到了最后,我們也僅僅是對(duì)AWK有了初步了解,更多細(xì)節(jié)還待認(rèn)真學(xué)習(xí),但所謂萬(wàn)法皆空,因果不空,執(zhí)行下面的命令,結(jié)束我們AWK的學(xué)習(xí)吧:
awk '{line[$0]++} END{for(i in line) delete line[i]}' ColorBlind.txt > ColorBlind.txt
參考
http://intro-to-awk.blogspot.jp/
http://coolshell.cn/articles/9070.html
http://www.infoworld.com/article/2985804/linux/remember-sed-awk-linux-admins-should.html