国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
為什么你應(yīng)該學(xué)點(diǎn)Awk(附指南及示范) By yuanyi

為什么你應(yīng)該學(xué)點(diǎn)Awk(附指南及示范)

在我還讀研究生時,我被一個我曾共事過的教授向我展示的高超文本文件操作能力震撼了,于是我決定花點(diǎn)時間學(xué)學(xué)他用來操作文本文件的神器Awk。

即便是在今天,我所認(rèn)識的90%的程序員幾乎從沒用過awk,其實(shí)只要你花上幾分鐘了解哪怕只是awk10%的語法,它都能夢幻般的提高你操作文本文件的能力。下面就讓我來教你一些最有用的操作——注意,不是“最基礎(chǔ)的”,只要你愿意花上5分鐘時間練習(xí)下這些技巧,我相信你就將會領(lǐng)悟到我認(rèn)為這門語言最為有趣的東西。

Awk實(shí)際上是一門非常有趣的小型編程語言,它設(shè)計的主要目的就是為了處理字符串。還記得有次我們的一個教授為我們布置了一道計算機(jī)網(wǎng)絡(luò)的課程作業(yè),讓我們根據(jù)RPC協(xié)議編寫一個可以生成客戶端和服務(wù)端stub的程序,但是這個教授犯了一個錯誤,他告訴我們可以使用任何我們想要的語言,于是我決定用Awk來寫一個,我原本的目的只是為了更好的掌握Awk,但是讓我驚奇的是,我發(fā)現(xiàn)最終我的實(shí)現(xiàn)要比其它我用過的語言(Python,C++,Java)都更簡短。

如果要了解Awk,你可以看看這本書,當(dāng)然我已經(jīng)看過了,但是你可能并不想像我那樣用Awk來實(shí)現(xiàn)某個協(xié)議的一個解析器,或許你只是想從你的日志文件中找出那些IP地址加起來剛好是666的家伙,那就跟我來吧,繼續(xù)往下看!

讓我們先來看個例子,假設(shè)我們有一個小文件(logs.txt)看起來像是下面這樣,很簡單,它只有2行帶有IP地址的log信息:

07.46.199.184 [28/Sep/2010:04:08:20] "GET /robots.txt HTTP/1.1" 200 0 "msnbot"
123.125.71.19 [28/Sep/2010:04:20:11] "GET / HTTP/1.1" 304 - "Baiduspider"

這是兩條由Apache生成的日志信息,很簡單,它們顯示了Bing和Baidu的爬蟲昨天到訪過我的網(wǎng)站。

Awk同其它命令行程序(比如grep)一樣,都是從stdin讀取輸入并寫到stdout,所以你可以很容易的通過管道使用它,Awk的使用也很簡單,你唯一需要關(guān)心的它令后面的那個字符串參數(shù):

awk '{print $0}'

大部分awk程度都是以{開頭,并以}結(jié)束的,{}中包含的命令會在輸入中的每一行上執(zhí)行,大部分awk程序都會打印些什么東西,上面的命令會原封不動的將它讀到的輸入再打印出來,并添加一個換行,$0代表一整行。所以這個程序很典型——它除了將輸入拷貝到輸出,其它什么都沒做。

Awk還會根據(jù)輸入行中的空白字符(空格,tab)自動將行切分為字段,并自動處理連著的分隔字符,你可以通過$1,$2,$3等來引用分割后的字段。

echo 'this is a test' | awk '{print $3}' // prints 'a'
awk '{print $1}' logs.txt

輸出:

07.46.199.184
123.125.71.19

很簡單,并且很有用,不是嗎?但是有時我需要從字符串的結(jié)尾開始打印,這時我可以使用一個名為NF的特殊變量,它包含了當(dāng)前行的字段數(shù),因此我可以使用$NF來打印最后一個字段,我也可以通過這個值來反向查找某個字段,同時我還可以在一行打印多個值:

echo 'this is a test' | awk '{print $NF}' // prints "test"
awk '{print $1, $(NF-2) }' logs.txt

輸出:

07.46.199.184 200
123.125.71.19 304

更進(jìn)一步——現(xiàn)在你可以看到,我們可以將日志文件分割,并只打印我們關(guān)心的部分。另一個很有用的變量就是NR,這個變量表示當(dāng)前正在處理的輸入的行號。在我演示NR的同時,我還想展示一下如何使用print來格式化輸出,你可以使用逗號來分隔print的多個參數(shù),它們會被轉(zhuǎn)化為空格,但是下面的例子我沒有使用逗號,所以結(jié)果中也沒有插入空格:

awk '{print NR ") " $1 " -> " $(NF-2)}' logs.txt

輸出:

1) 07.46.199.184 -> 200
2) 123.125.71.19 -> 304

很強(qiáng)大,并且一點(diǎn)也不難,對吧,如果你喜歡,你還可以使用printf函數(shù),或許你對它更熟一些?,F(xiàn)在,問題來了,不是所有字段都是以空格作為分隔符的,比如下面這個:

$ awk '{print $2}' logs.txt

輸出:

[28/Sep/2010:04:08:20]
[28/Sep/2010:04:20:11]

日期字段使用了/和:作為分隔符,當(dāng)然我可以通過一條awk命令來完成這個操作,但是我想向你演示一種更簡單也是你更為熟悉的方式:Unix管道,下面我要做的就是通過管道使用另外一條awk命令來根據(jù)冒號對日期進(jìn)行分割,要做到這一點(diǎn),我的第二個awk命令需要使用2個{},不過我暫時不想對這個多做解釋,你只要看看我是如何做的就行了:

$ awk '{print $2}' logs.txt | awk 'BEGIN{FS=":"}{print $1}'

輸出:

[28/Sep/2010
[28/Sep/2010

我為FS(也就是字段分隔符)指定了一個不同的值,也就是":",然后打印出了第一個字段,現(xiàn)在沒有時間了,只有日期!如果你不想看到輸出中的那個[,最簡單的方法就是使用sed,或許你早就知道了:

$ awk '{print $2}' logs.txt | awk 'BEGIN{FS=":"}{print $1}' | sed 's/\[//'

輸出:

28/Sep/2010
28/Sep/2010

使用相同的技巧,我還可以進(jìn)一步根據(jù)'/‘字符來切分日期,但是我認(rèn)為你已經(jīng)掌握這個技巧了,所以我就不羅嗦了,下面,讓我們來試著加入一點(diǎn)點(diǎn)邏輯判斷,如果我只想得到狀態(tài)為200的行,我可以使用grep,但是如果我想得到IP地址中包含200的行,或者是日期在2000年以后的行,那我就需要先使用awk,然后在通過grep來查找了,不過的問題是輸出結(jié)果沒了上下文,還好,Awk支持if條件判斷,所以我們可以像下面這樣:

$ awk '{if ($(NF-2)=="200") {print $0}}' logs.txt

輸出:

07.46.199.184 [28/Sep/2010:04:08:20] "GET /robots.txt HTTP/1.1" 200 0 "msnbot"

現(xiàn)在,只有符合條件的行才會被輸出,這個if語句實(shí)在是太熟悉不過了,應(yīng)該不需要我做過多的解釋,下面讓我通過一個蠢例子向你演示下awk如何實(shí)現(xiàn)跨行保存狀態(tài),假設(shè)我想得到這個文件中所有HTTP相應(yīng)的狀態(tài)字段的和,雖然我實(shí)在想不出有有什么理由這樣做,但是為了演示字段求和,就讓我們先忘掉這一點(diǎn)吧,要做到這一點(diǎn),我只需要創(chuàng)建一個變量就okay了:

$ awk '{a+=$(NF-2); print "Total so far:", a}' logs.txt

輸出:

Total so far: 200
Total so far: 504

很顯然,這是有問題的,大部分情況下,我并不需要中間值,只需要最后的結(jié)果就可以了,當(dāng)然我可以使用tail -n1,但是還有一種更好的方式,我可以使用END關(guān)鍵字告訴awk只在最后一行調(diào)用print:

$ awk '{a+=$(NF-2)}END{print "Total:", a}' logs.txt

輸出:

Total: 504

如果你想要了解更多關(guān)于awk的知識,有幾本好書以及大量的線上資源可供你參考,只需要花上一些閑暇時間,你就可以很容易的學(xué)到關(guān)于awk的一切,但是要熟練使用它,還是有些挑戰(zhàn)的,因?yàn)樗木幋a方式實(shí)在有點(diǎn)特別——你實(shí)際上是在寫一個for循環(huán)的內(nèi)部實(shí)現(xiàn),仔細(xì)想想,這其實(shí)有點(diǎn)MapReduce的感覺,只是一開始會讓人有些迷惑。

我希望這篇文章能對你有用,如果你覺得它有用,不妨給我留言。

更新: 這篇文章的許多評論都很值得一讀,當(dāng)然我很希望它們都能在一個地方,但現(xiàn)在我只能把它們分別列出來:

Programming Reddit
Hacker News

最后,如果你是那種對awk感興趣的人,毫無疑問,你就是那種我希望可以在Google共事的人,如果你感興趣,可以給我簡歷(ggrothau@gmail.com),我可以確保它一定會出現(xiàn)在合適的招聘者面前,而不是遺落在我們每天收到的那一大堆簡歷中。

--------------
本文來自"Why you should learn just a little Awk - A Tutorial by Example",作者:Greg,翻譯:@yuanyiz

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
linux Shell學(xué)習(xí)筆記第一天
Linux必學(xué)技能:文本操作三劍客(awk/sed/grep)應(yīng)用實(shí)例
常用文本處理命令
shell中字符串截取命令:cut,printf,awk,sed
Linux awk
Linux文本處理三劍客之a(chǎn)wk學(xué)習(xí)筆記03:讀取文件
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服