我們先來用專業(yè)的術(shù)語描述一下awk是什么虎韵,如果你看不懂,沒關(guān)系缸废,我們會(huì)再用"大白話"解釋一遍包蓝。
awk是一個(gè)報(bào)告生成器,它擁有強(qiáng)大的文本格式化的能力企量,這就是專業(yè)的說法测萎。
你可能不理解所謂的報(bào)告生成器中的"報(bào)告"是什么,你可以把"報(bào)告"理解為"報(bào)表"或者"表格",也就是說届巩,我們可以利用awk命令绳泉,將一些文本整理成我們想要的樣子,比如把一些文本整理成"表"的樣子姆泻,然后再展示出來零酪,剛才概念中提到的"文本格式化的能力",也就是這個(gè)意思拇勃,其實(shí)這樣說可能還是不太容易理解四苇,不用著急,當(dāng)你看到后面的"示例"時(shí)方咆,自然會(huì)明白awk所擅長(zhǎng)的"文本格式化"能力是什么月腋。
awk是由Alfred Aho 、Peter Weinberger 和 Brian Kernighan這三個(gè)人創(chuàng)造的瓣赂,awk由這個(gè)三個(gè)人的姓氏的首個(gè)字母組成榆骚。
awk早期是在unix上實(shí)現(xiàn)的,所以煌集,我們現(xiàn)在在linux的所使用的awk其實(shí)是gawk妓肢,也就是GNU awk,簡(jiǎn)稱為gawk苫纤,awk還有一個(gè)版本碉钠,New awk,簡(jiǎn)稱為nawk卷拘,但是linux中最常用的還是gawk喊废。
awk其實(shí)是一門編程語言,它支持條件判斷栗弟、數(shù)組污筷、循環(huán)等功能。所以乍赫,我們也可以把a(bǔ)wk理解成一個(gè)腳本語言解釋器瓣蛀。
grep 斤寂、sed、awk被稱為linux中的"三劍客"揪惦。
我們總結(jié)一下這三個(gè)"劍客"的特長(zhǎng)。
grep 更適合單純的查找或匹配文本
sed ?更適合編輯匹配到的文本
awk ?更適合格式化文本罗侯,對(duì)文本進(jìn)行較復(fù)雜格式處理
此處器腋,我們只總結(jié) awk
awk基礎(chǔ)
awk基本語法如下,看不懂沒關(guān)系钩杰,我們會(huì)慢慢舉例纫塌。
awk [options] 'program' file1 , file2 , ```
對(duì)于上述語法中的program來說,又可以細(xì)分成pattern和action讲弄,也就是說措左,awk的基本語法如下
awk [options] 'Pattern{Action}' file
從字面上理解 ,action指的就是動(dòng)作避除,awk擅長(zhǎng)文本格式化怎披,并且將格式化以后的文本輸出,所以awk最常用的動(dòng)作就是print和printf瓶摆,因?yàn)閍wk要把格式化完成后的文本輸出啊凉逛,所以,這兩個(gè)動(dòng)作最常用群井。
我們先從最簡(jiǎn)單用法開始了解awk状飞,我們先不使用[options] ,也不指定pattern,直接使用最簡(jiǎn)單的action书斜,從而開始認(rèn)識(shí)awk诬辈,示例如下
上圖中,我們只是使用awk執(zhí)行了一個(gè)打印的動(dòng)作荐吉,將testd文件中的內(nèi)容打印了出來焙糟。
好了,現(xiàn)在样屠,我們來操作一下另一個(gè)類似的場(chǎng)景酬荞。
上圖中的示例沒有使用到options和pattern,上圖中的awk '{print $5}'瞧哟,表示輸出df的信息的第5列混巧,$5表示將當(dāng)前行按照分隔符分割后的第5列,不指定分隔符時(shí)勤揩,默認(rèn)使用空格作為分隔符咧党,細(xì)心的你一定發(fā)現(xiàn)了,上述信息用的空格不止有一個(gè)陨亡,而是有連續(xù)多個(gè)空格傍衡,awk自動(dòng)將連續(xù)的空格理解為一個(gè)分割符了深员,是不是比cut命令要簡(jiǎn)單很多,這樣比較簡(jiǎn)單的例子蛙埂,有利于我們開始了解awk倦畅。
awk是逐行處理的,逐行處理的意思就是說绣的,當(dāng)awk處理一個(gè)文本時(shí)叠赐,會(huì)一行一行進(jìn)行處理,處理完當(dāng)前行屡江,再處理下一行芭概,awk默認(rèn)以"換行符"為標(biāo)記,識(shí)別每一行惩嘉,也就是說罢洲,awk跟我們?nèi)祟愐粯樱看斡龅?回車換行"文黎,就認(rèn)為是當(dāng)前行的結(jié)束惹苗,新的一行的開始,awk會(huì)按照用戶指定的分割符去分割當(dāng)前行耸峭,如果沒有指定分割符鸽粉,默認(rèn)使用空格作為分隔符。
$0 表示顯示整行 抓艳,$NF表示當(dāng)前行分割后的最后一列($0和$NF均為內(nèi)置變量)
注意触机,$NF 和 NF 要表達(dá)的意思是不一樣的,對(duì)于awk來說玷或,$NF表示最后一個(gè)字段儡首,NF表示當(dāng)前行被分隔符切開以后,一共有幾個(gè)字段偏友。
也就是說蔬胯,假如一行文本被空格分成了7段,那么NF的值就是7位他,$NF的值就是$7, ?而$7表示當(dāng)前行的第7個(gè)字段氛濒,也就是最后一列,那么每行的倒數(shù)第二列可以寫為$(NF-1)鹅髓。
我們也可以一次輸出多列舞竿,使用逗號(hào)隔開要輸出的多個(gè)列,如下窿冯,一次性輸出第一列和第二列
同理骗奖,也可以一次性輸出多個(gè)指定的列,如下圖
我們發(fā)現(xiàn),第一行并沒有第5列执桌,所以并沒有輸出任何文本鄙皇,而第二行有第五列,所以輸出了仰挣。
除了輸出文本中的列伴逸,我們還能夠添加自己的字段,將自己的字段與文件中的列結(jié)合起來膘壶,如下做法错蝴,都是可以的。
從上述實(shí)驗(yàn)中可以看出香椎,awk可以靈活的將我們指定的字符與每一列進(jìn)行拼接,或者把指定的字符當(dāng)做一個(gè)新列插入到原來的列中禽篱,也就是awk格式化文本能力的體現(xiàn)畜伐。
但是要注意,$1這種內(nèi)置變量的外側(cè)不能加入雙引號(hào)躺率,否則$1會(huì)被當(dāng)做文本輸出玛界,示例如下
我們也可以輸出整行,比如悼吱,如下兩種寫法都表示輸出整行慎框。
我們說過,awk的語法如下
awk [options] 'Pattern{Action}' file
而且我們說過awk是逐行處理的后添, 剛才已經(jīng)說過了最常用的Action:print
現(xiàn)在笨枯,我們來認(rèn)識(shí)下一Pattern,也就是我們所說的模式
不過遇西,我們準(zhǔn)備先把a(bǔ)wk中最特殊的模式展示給大家馅精,以后再介紹普通的模式,因?yàn)槠胀J叫枰钠容^長(zhǎng)粱檀,所以我們先來總結(jié)特殊模式洲敢。
AWK 包含兩種特殊的模式:BEGIN?和?END。
BEGIN?模式指定了處理文本之前需要執(zhí)行的操作:
END?模式指定了處理完所有行之后所需要執(zhí)行的操作:
什么意思呢茄蚯?光說不練不容易理解压彭,我們來看一些小例子,先從BEGIN模式開始渗常,示例如下
上述寫法表示壮不,在開始處理test文件中的文本之前,先執(zhí)行打印動(dòng)作皱碘,輸出的內(nèi)容為"aaa","bbb".
也就是說忆畅,上述示例中,雖然指定了test文件作為輸入源,但是在開始處理test文本之前家凯,需要先執(zhí)行BEGIN模式指定的"打印"操作
既然還沒有開始逐行處理test文件中的文本缓醋,那么是不是根本就不需要指定test文件呢,我們來試試绊诲。
經(jīng)過實(shí)驗(yàn)發(fā)現(xiàn)送粱,還真是,我們并沒有給定任何輸入來源掂之,awk就直接輸出信息了抗俄,因?yàn)椋珺EGIN模式表示世舰,在處理指定的文本之前动雹,需要先執(zhí)行BEGIN模式中指定的動(dòng)作,而上述示例沒有給定任何輸入源跟压,但是awk還是會(huì)先執(zhí)行BEGIN模式指定的"打印"動(dòng)作胰蝠,打印完成后,發(fā)現(xiàn)并沒有文本可以處理震蒋,于是就只完成了"打印 aaa bbb"的操作茸塞。
這個(gè)時(shí)候,如果我們想要awk先執(zhí)行BEGIN模式指定的動(dòng)作查剖,再根據(jù)執(zhí)我們自定義的動(dòng)作去操作文本钾虐,該怎么辦呢?示例如下
上圖中笋庄,藍(lán)色標(biāo)注的部分表示BEGIN模式指定的動(dòng)作效扫,這部分動(dòng)作需要在處理指定的文本之前執(zhí)行,所以直砂,上圖中先打印出了"aaa bbb"荡短,當(dāng)BEGIN模式對(duì)應(yīng)的動(dòng)作完成后,在使用后面的動(dòng)作處理對(duì)應(yīng)的文本哆键,即打印test文件中的第一列與第二列掘托,這樣解釋應(yīng)該比較清楚了吧。
看完上述示例籍嘹,似乎更加容易理解BEGIN模式是什么意思了闪盔,BEGIN模式的作用就是,在開始逐行處理文本之前辱士,先執(zhí)行BEGIN模式所指定的動(dòng)作泪掀。以此類推,END模式的作用就一目了然了颂碘,舉例如下异赫。
聰明如你一定明白了,END模式就是在處理完所有的指定的文本之后,需要指定的動(dòng)作塔拳。
那么鼠证,我們可以結(jié)合BEGIN模式和END模式一起使用。示例如下
上述示例中返回的結(jié)果有沒有很像一張"報(bào)表"靠抑,有"表頭" ?量九、"表內(nèi)容"、 ?"表尾"颂碧,awk對(duì)文本的格式化能力你體會(huì)到了嗎荠列?