天天看點

shell學習筆記1---awk基礎(原創)

awk概述

awk是一種程式設計語言,用于在linux/unix下對文本和資料進行處理。資料可以來自标準輸入、一個或多個檔案,或其它指令的輸出。它支援使用者自定義函數和 動态正規表達式等先進功能,是linux/unix下的一個強大程式設計工具。它在指令行中使用,但更多是作為腳本來使用。awk的處理文本和資料的方式是這 樣的,它逐行掃描檔案,從第一行到最後一行,尋找比對的特定模式的行,并在這些行上進行你想要的操作。如果沒有指定處理動作,則把比對的行顯示到标準輸出 (螢幕),如果沒有指定模式,則所有被操作所指定的行都被處理。awk分别代表其作者姓氏的第一個字母。因為它的作者是三個人,分别是alfred aho、brian kernighan、peter weinberger。gawk是awk的gnu版本,它提供了bell實驗室和gnu的一些擴充。下面介紹的awk是以gun的gawk為例的,在 linux系統中已把awk連結到gawk,是以下面全部以awk進行介紹。

awk概念

模式和動作

任何a w k語句都由模式和動作組成。在一個a w k腳本中可能有許多語句。模式部分決定動

作語句何時觸發及觸發事件。處理即對資料進行的操作。如果省略模式部分,動作将時刻保

持執行狀态。

模式可以是任何條件語句或複合語句或正規表達式。模式包括兩個特殊字段begin和e n d。使用b e g i n語句設定計數和列印頭。b e g i n語句使用在任何文本浏覽動作之前,之後文本浏覽動作依據輸入檔案開始執行。end語句用來在a w k完成文本浏覽動作後列印輸出文本總數和結尾狀态标志。如果不特别指明模式,a w k總是比對或列印行數。實際動作在大括号{ }内指明。動作大多數用來列印,但是還有些更長的代碼諸如i f和循環(looping)語句及循環退出結構。如果不指明采取動作,a w k将列印出所有浏覽出來的記錄

記錄

awk把每一個以換行符結束的行稱為一個記錄。

記錄分隔符:預設的輸入和輸出的分隔符都是回車,儲存在内建變量ors和rs中。

$0變量:它指的是整條記錄。如$ awk '{print $0}' test将輸出test檔案中的所有記錄。

變量nr:一個計數器,每處理完一條記錄,nr的值就增加1。如$ awk '{print nr,$0}' test将輸出test檔案中所有記錄,并在記錄前顯示記錄号。

記錄中每個單詞稱做“域”,預設情況下以空格或tab分隔。awk可跟蹤域的個數,并在内建變量nf中儲存該值。如$ awk '{print $1,$3}' test将列印test檔案中第一和第三個以空格分開的列(域)。

域分隔符

内建變量fs儲存輸入域分隔符的值,預設是空格或tab。我們可以通過-f指令行選項修改fs的值。如$ awk -f: '{print $1,$5}' test将列印以冒号為分隔符的第一,第五列的内容。

符寫成放到方括号中,如$awk -f'[:\t]' '{print $1,$3}' test,表示以空格、冒号和tab作為分隔符。

輸出域的分隔符預設是一個空格,儲存在ofs中。如$ awk -f: '{print $1,$5}' test,$1和$5間的逗号就是ofs的值。

域和記錄操作

$cat grade.txt

m.tans 5/99 48311 green 8 40 44

j.lulu 06/99 48317 green 9 24 26

p.bunny 02/99 48 yellow 12 35 28

j.troll 07/99 4842 brown-3 12 26 26

l.tansl 05/99   4712 brown-2 12 30 28

此文本檔案有7個域,即(1)名字、(2)升段日期、(3)學生序号、(4)腰帶級别、(5)年齡、(6)目前比賽積分、(7)比賽最高分。

因為域間使用空格作為域分隔符,故不必用- f選項劃分域,現浏覽檔案并導出一些資料。在例子中為了利于顯示,将空格加寬使各域看得更清晰。

1、儲存awk輸出

有兩種方式儲存shell提示符下awk腳本的輸出。最簡單的方式是使用輸出重定向符号>檔案名,下面的例子重定向輸出到檔案wow。

$awk "{print $0}" grade.txt >wow

使用這種方法要注意,顯示屏上不會顯示輸出結果。因為它直接輸出到檔案。隻有在保證輸出結果正确時才會使用這種方法。它也會重寫硬碟上同名資料。

第二種方法是使用tee指令,在輸出到檔案的同時輸出到螢幕。在測試輸出結果正确與否時多使用這種方法。例如輸出重定向到檔案delete_me_and_die,同時輸出到螢幕。使用這種方法,在awk指令結尾寫入| tee delete_me_and_die。

$awk "{print $0}" grade.txt | tee delete_me_and_die

2. 使用标準輸入

在深入講解這一章之前,先對awk腳本的輸入方法簡要介紹一下。實際上任何腳本都是從标準輸入中接受輸入的。為運作本章腳本,使用awk腳本輸入檔案格式,例如:belts.awk grade_student.txt

也可替代使用下述格式:

使用重定向方法:

belts.awk < grade2.txt

或管道方法:

grade2.txt | belts.awk

3 列印所有記錄

$awk '{print $0}' grade.txt

awk讀每一條記錄。因為沒有模式部分,隻有動作部分{print $0}(列印所有記錄),這個動作必須用花括号括起來。上述指令列印整個檔案。

4. 列印單獨記錄

假定隻列印學生名字和腰帶級别,通過檢視域所在列,可知為field-1和field-4,是以可以使用$1和$4,但不要忘了加逗号以分隔域。

$awk '{print $1,$4}' grade.txt

m.tans green

j.lulu green

p.bunny yellow

j.troll brown-3

l.tansl brown-2

5. 列印報告頭

上述指令輸出在名字和腰帶級别之間用一些空格使之更容易劃分,也可以在域間使用tab鍵加以劃分。為加入tab鍵,使用tab鍵速記引用符\t,後面将對速記引用加以詳細讨論。也可以為輸出文本加入資訊頭。本例中加入name和belt及下劃線。下劃線使用\n,強迫啟動新行,并在\n下一行啟動列印文本操作。列印資訊頭放置在begin模式部分,因為列印資訊頭被界定為一個動作,必須用大括号括起來。在awk檢視第一條記錄前,資訊頭被列印。

$awk 'begin {print "name belt\n-----------------------------------"}{print $1"\t",$4}' grade.txt

name belt

-----------------------------------

m.tans   green

j.lulu   green

p.bunny  yellow

j.troll  brown-3

l.tansl  brown-2

6. 列印資訊尾

如果在末行加入end of report資訊,可使用end語句。end語句在所有文本處理動作執行完之後才被執行。end語句在腳本中的位置放置在主要動作之後。下面簡單列印頭資訊并告之查詢動作完成。

$awk 'begin {print "name\n--------"}{print $1} end {print "end-of-report"}' grade.txt

name

--------

m.tans

j.lulu

p.bunny

j.troll

l.tansl

end-of-report

7. awk錯誤資訊提示

幾乎可以肯定,在使用awk時,将會在指令中碰到一些錯誤。awk将試圖列印錯誤行,但由于大部分指令都隻在一行,是以幫助不大。

系統給出的顯示錯誤資訊提示可讀性不好。使用上述例子,如果丢了一個雙引号, awk将傳回:

$awk 'begin {print "name\n--------}{print $1} end {"end-of-report"}' grade.txt

awk: cmd. line:1: begin {print "name\n--------}{print $1} end {"end-of-report"}

awk: cmd. line:1:                                                            ^ unterminated string

當第一次使用awk時,可能被錯誤資訊攪得不知所措,但通過長時間和不斷的學習,可總結出以下規則。在碰到awk錯誤時,可相應查找:

確定整個awk指令用單引号括起來。

確定指令内所有引号成對出現。

確定用花括号括起動作語句,用圓括号括起條件語句。

可能忘記使用花括号,也許你認為沒有必要,但awk不這樣認為,将按之解釋文法。

如果查詢檔案不存在,将得到下述錯誤資訊:

$awk 'end {print nr}' grades.txt

awk: cmd. line:2: fatal: cannot open file 'grades.txt' for reading (沒有那個檔案或目錄)

8.awk 鍵盤輸入

如果在指令行并沒有輸入檔案grade.txt,将會怎樣?

$awk 'begin {print "name\n--------"}{print $1} end {"end-of-report"}'

begin部分列印了檔案頭,但awk最終停止操作并等待,并沒有傳回shell提示符。這是因為awk期望獲得鍵盤輸入。因為沒有給出輸入檔案,awk假定下面将會給出。如果願意,順序輸入相關文本,并在輸入完成後敲<ctrl-d>鍵。如果敲入了正确的域分隔符,awk會像第一個例子一樣正常處理文本。這種處理并不常用,因為它大多應用于大量的列印稿。

元字元

這裡是awk中正規表達式比對操作中經常用到的字元。

\ ^ $. [] | () * + ?

這裡有兩個字元隻适用于awk而不适用于grep或sed。它們是:

+ 使用+比對一個或多個字元。

?比對模式出現頻率。例如使用/x y?z/比對x y z或y z。

條件操作符

awk條件操作符

操作符描述

<

小于

>=

大于等于

<=

小于等于

==

等于

~

比對正規表達式

!~

不比對正規表達式

!=

不等于

1.比對

為使一域号比對正規表達式,使用符号'~'後緊跟正規表達式,也可以用if語句。awk中if後面的條件用()括起來。

觀察檔案grade.txt,如果隻要顯示brown腰帶級别可知其所在域為field-4,這樣可以寫出表達式{if($4~/brown/) print}意即如果field-4包含brown,列印它。如果條件滿足,則列印比對記錄行。可以編寫下面腳本,因為這是一個動作,必須用花括号{ }括起來。

# awk '{if($4~/brown/) print $0}' grade.txt

l.tansl 05/99 4712 brown-2 12 30 28

比對記錄找到時,如果不特别聲明, awk預設列印整條記錄。使用if語句開始有點難,但不要着急,因為有許多方法可以跳過它,并仍保持同樣結果。下面例子意即如果記錄包含模式brown,就列印它:

# awk '$0 ~ /brown/' grade.txt

2.精确比對

假定要使字元串精确比對,比如說檢視學生序号48,檔案中有許多學生序号包含48,如果在field-3中查詢序号48,awk将傳回所有序号帶48的記錄:

# awk '{if($3~/48/) print$0}' grade.txt

為精确比對48,使用等号==,并用單引号括起條件。例如$3

# awk '$3=="48" {print$0}' grade.txt

# awk '{if($3=="48") print$0}' grade.txt

3.不比對

有時要浏覽資訊并抽取不比對操作的記錄,與~相反的符号是!~,意即不比對。像原來使用查詢brown腰帶級别的比對操作一樣,現在看看不比對情況。表達式$0 !~/brown/,意即查詢不包含模式brown腰帶級别的記錄并列印它。

注意,預設情況下, awk将列印所有比對記錄,是以這裡不必加入動作部分。

# awk '$0 !~ /brown/' grade.txt

可以隻對field-4進行不比對操作,方法如下:

如果隻使用指令awk$4 !="brown"{print $0} grade.txt,将傳回錯誤結果,因為用引号括起了brown,将隻比對'brown而不比對brown-2和brown-3,當然,如果想要查詢非brown-2的腰帶級别,可做如下操作:

# awk '$4!="brown-2" {print $0}' grade.txt

4.小于

看看哪些學生可以獲得升段機會。測試這一點即判斷目前級别分field-6是否小于最高分field-7,在輸出結果中,加入這一改動很容易。

# awk '{if($6 < $7) print $0}' grade.txt

5.小于等于

對比小于,小于等于隻在操作符上做些小改動,滿足此條件的記錄也包括上面例子中的輸出情況。

# awk '{if($6 <= $7) print $1}' grade.txt

6.大于

# awk '{if($6 > $7) print $1}' grade.txt

7.設定大小寫

為查詢大小寫資訊,可使用[ ]符号。在測試正規表達式時提到可比對[ ]内任意字元或單詞,是以若查詢檔案中級别為green的所有記錄,不論其大小寫,表達式應為'/[gg]reen/'

# awk '/[gg]reen/' grade.txt

8.任意字元

抽取名字,其記錄第一域的第四個字元是a,使用句點.。表達式/^...a/意為行首前三個字元任意,第四個是a,尖角符号代表行首。

# awk '$1 ~ /^...a/' grade.txt

9.或關系比對

為抽取級别為yellow或brown的記錄,使用豎線符|。意為比對|兩邊模式之一。注意,使用豎線符時,語句必須用圓括号括起來。

# awk '$0 ~/(yellow|brown)/' grade.txt

上面例子輸出所有級别為ye l l o w或brown的記錄。

使用這種方法在查詢級别為green或green時,可以得到與使用[ ]表達式相同的結果。

# awk '/^m/' grade.txt

行首

不必總是使用域号。如果查詢文本檔案行首包含m的代碼,可簡單使用下面^符号:

複合表達式即為模式間通過使用下述各表達式互相結合起來的表達式:

&& and : 語句兩邊必須同時比對為真。

|| or:語句兩邊同時或其中一邊比對為真。

! 非求逆

10. and

列印記錄,使其名字為'p.bunny且級别為yellow,使用表達式($1=="p.bunny" && $4=="yellow"),意為&&兩邊比對均為真。完整指令如下:

# awk '{if ($1=="p.bunny" && $4=="yellow") print $0}' grade.txt

11. or

如果查詢級别為yellow或brown,使用或指令。意為"||"符号兩邊的比對模式之一或全部為真。

# awk '{if ($4=="yellow" || $4~/brown/) print $0}' grade.txt

原來不一定得加print,下面我自己對例一二做了一下

1

# awk '$4~/brown/' grade.txt

2

# awk '$3=="48"' grade.txt

# awk '$3="48"' grade.txt

m.tans 5/99 48 green 8 40 44

j.lulu 06/99 48 green 9 24 26

j.troll 07/99 48 brown-3 12 26 26

l.tansl 05/99 48 brown-2 12 30 28

2中,我把=和==寫錯了,呵呵,一個是指派,一個是等于

awk内置變量

awk有許多内置變量用來設定環境資訊。這些變量可以被改變。

argc:指令行參數個數

argv:指令行參數排列

argind 目前被處理檔案的argv标志符

environ:支援隊列中系統環境變量的使用

filename:awk浏覽的檔案名

fnr:浏覽檔案的記錄數

fs:設定輸入域分隔符,等價于指令行-f選項

nf:浏覽記錄的域個數

nr:已讀的記錄數

ofs:輸出域分隔符

ors:輸出記錄分隔符

rs:控制記錄分隔符

argc支援指令行中傳入awk腳本的參數個數。argv是argc的參數排列數組,其中每一進制素表示為argv [n],n為期望通路的指令行參數。

environ支援系統設定的環境變量,要通路單獨變量,使用實際變量名,例如environ ["editor"]="vi"。

filename支援awk腳本實際操作的輸入檔案。因為awk可以同時處理許多檔案,是以如果通路了這個變量,将告之系統目前正在浏覽的實際檔案。

fnr支援awk目前操作的記錄數。其變量值小于等于nr。如果腳本正在通路許多檔案,每一新輸入檔案都将重新設定此變量。

fs用來在awk中設定域分隔符,與指令行中-f選項功能相同。預設情況下為空格。如果用逗号來作域分隔符,設定fs=","。

nf支援記錄域個數,在記錄被讀之後再設定。

ofs允許指定輸出域分隔符,預設為空格。如果想設定為#,寫入ofs="#"。

ors為輸出記錄分隔符,預設為新行(\n)。

rs是記錄分隔符,預設為新行(\n)。

nf、nr和filename

要快速檢視記錄個數,應使用nr。比如說導出一個資料庫檔案後,如果想快速浏覽記錄個數,以便對比于其初始狀态,查出導出過程中出現的錯誤。使用nr将列印輸入檔案的記錄個數。print nr放在end文法中。

# awk 'end{print nr}' grade.txt

5

如:所有學生記錄被列印,并帶有其記錄号。使用nf變量顯示每一條讀記錄中有多少個域,并在end部分列印輸入檔案名。

# awk '{print nf,nr,$0} end{print filename}' grade.txt

7 1 m.tans 5/99 48311 green 8 40 44

7 2 j.lulu 06/99 48317 green 9 24 26

7 3 p.bunny 02/99 48 yellow 12 35 28

7 4 j.troll 07/99 4842 brown-3 12 26 26

7 5 l.tansl 05/99       4712 brown-2 12 30 28

grade.txt

在從檔案中抽取資訊時,最好首先檢查檔案中是否有記錄。下面的例子隻有在檔案中至少有一個記錄時才查詢brown級别記錄。使用and複合語句實作這一功能。意即至少存在一個記錄後,查詢字元串brown,最後列印結果。

# awk '{if (nr>0 && $4~/brown/)print $0}' grade.txt

nf的一個強大功能是将變量$pwd的傳回值傳入awk并顯示其目錄。這裡需要指定域分隔符/。

# echo $pwd | awk -f/ ' {print $nf}'

sam

另一個例子是顯示檔案名。

# echo "/usr/local/etc/rc.sybase" | awk -f/ '{print $nf}'

rc.sybase

如果不指定域分割符,傳回的如下:

# echo $pwd | awk '{print $nf}'

/usr/sam

# echo "/usr/local/etc/rc.sybase" | awk '{print $nf}'

/usr/local/etc/rc.sybase

awk的其他操作

1. 設定輸入域到域變量名

在awk中,設定有意義的域名是一種好習慣,在進行模式比對或關系操作時更容易了解。一般的變量名設定方式為name=$n,這裡name為調用的域變量名, n為實際域号。例如設定學生域名為name,級别域名為belt,操作為name=$1;belt s=$4。注意分号的使用,它分隔awk指令。

下面例子中,重新指派學生名域為name,級别域為belts。查詢級别為yellow的記錄,并最終列印名稱和級别。

$awk '{name=$1;belts=$4;if(belts ~/yellow/) print name" is belt "belts}' grade.txt

p.bunny is belt yellow

2. 域值比較操作

有兩種方式測試一數值域是否小于另一數值域。

1) 在begin中給變量名指派。

2) 在關系操作中使用實際數值。

通常在begin部分指派是很有益的,可以在awk表達式進行改動時減少很多麻煩。

使用關系操作必須用圓括号括起來。

下面的例子查詢所有比賽中得分在27點以下的學生。用引号将數字引用起來是可選的,"27"、27産生同樣的結果。

$awk '{if ($6<"27") print $0}' grade.txt

第二個例子中給數字賦以變量名baseline和在begin部分給變量指派,兩者意義相同。

$awk 'begin{baseline="27"} {if ($6<baseline) print $0}' grade.txt

3. 修改數值域取值

當在awk中修改任何域時,重要的一點是要記住實際輸入檔案是不可修改的,修改的隻是儲存在緩存裡的awk複本。awk會在變量nr或nf變量中反映出修改痕迹。

為修改數值域,簡單的給域辨別重賦新值,如:$1=$1+5,會将域1數值加5,但要確定指派域其子集為數值型。

修改m.tansley的目前級别分域,使其數值從40減為39,使用指派語句$6=$6-1,當然在實施修改前首先要比對域名。

$awk '{$6=$6-1;print $1,$6,$7}' grade.txt

m.tans 39 44

j.lulu 24 26

p.bunny 35 28

j.troll 26 26

l.tansl 30 28

$awk '{if($1=="m.tans") {$6=$6-1;print $1,$6,$7}}' grade.txt

4. 修改文本域

修改文本域即對其重新指派。需要做的就是賦給一個新的字元串。在j.troll中加入字母,使其成為j.l.troll,表達式為$1="j.l.troll",記住字元串要使用雙引号,并用圓括号括起整個文法。

$awk '{if($1=="j.troll") $1="j.l.troll"; print $1}' grade.txt

j.l.troll

5. 隻顯示修改記錄

上述例子均是對一個小檔案的域進行修改,是以列印出所有記錄檢視修改部分不成問題,但如果檔案很大,記錄甚至超過1 0 0,列印所有記錄隻為檢視修改部分顯然不合情理。在模式後面使用花括号将隻列印修改部分。取得模式,再根據模式結果實施操作,可能有些抽象,現舉一例,隻列印修改部分。注意花括号的位置。

$awk '{if($1=="j.troll") {$1="j.l.troll";print $1}}' grade.txt  

6. 建立新的輸出域

在awk中處理資料時,基于各域進行計算時建立新域是一種好習慣。建立新域要通過其他域賦予新域辨別符。如建立一個基于其他域的加法新域{$4=$2+$3},這裡假定記錄包含3個域,則域4為建立域,儲存域2和域3相加結果。

在檔案grade.txt中建立新域8儲存域目前級别分與域最進階别分的減法值。表達式為'{$8=$7-$6}',文法首先測試域目前級别分小于域最進階别分。新域是以隻列印其值大于零的學生名稱及其新域值。在begin部分加入tab鍵以對齊報告頭。

$awk 'begin{print "name\tdifference"}{if($6<$7) {$8=$7-$6;print $1,$8}}' grade.txt

name    difference

m.tans 4

j.lulu 2

當然可以建立新域,并賦給其更有意義的變量名。例如:

$awk 'begin{print "name\tdifference"}{if($6<$7) {diff=$7-$6;print $1,diff}}' grade.txt

7. 增加列值

為增加列數或進行運作結果統計,使用符号+=。增加的結果賦給符号左邊變量值,增加到變量的域在符号右邊。例如将$1加入變量total,表達式為total+=$1。列值增加很有用。許多檔案都要求統計總數,但輸出其統計結果十分繁瑣。在awk中這很簡單,請看下面的例子。

将所有學生的'目前級别分'加在一起,方法是tot+=$6,tot即為awk浏覽的整個檔案的域6結果總和。所有記錄讀完後,在end部分加入一些提示資訊及域6總和。不必在awk中顯示說明列印所有記錄,每一個操作比對時,這是預設動作。

$awk '(tot+=$6); end{print "club student total points :" tot}' grade.txt

club student total points :155

如果檔案很大,你隻想列印結果部分而不是所有記錄,在語句的外面加上圓括号()即可。

$awk '{(tot+=$6)}; end{print "club student total points :" tot}' grade.txt

8. 檔案長度相加

在目錄中檢視檔案時,如果想快速檢視所有檔案的長度及其總和,但要排除子目錄,使用ls -l指令,然後管道輸出到awk,awk首先剔除首字元為d(使用正規表達式)的記錄,然後将檔案長度列相加,并輸出每一檔案長度及在end部分輸出所有檔案的長度。

本例中,首先用ls -l指令檢視一下檔案屬性。注意第二個檔案屬性首字元為d,說明它是一個目錄,檔案長度是第5列,檔案名是第9列。如果系統不是這樣排列檔案名及其長度,應适時加以改變。

下面的正規表達式表明必須比對行首,并排除字元d,表達式為^[^d]。使用此模式列印檔案名及其長度,然後将各長度相加放入變量tot中。

$ls -l | awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} end {print "total kb:" tot}'

...................

total kb:174144

執行個體示範

$ cat employees2

tom jones:4432:5/12/66:543354

marry adams:5436:11/4/63:28765

sally chang:1655:7/22/54:650000

billy black:1683:9/23/44:336500

列印出以“:”為域分隔符中第4域小于30000的記錄

$ awk -f: '{if($4<300000) print $0}' employee2 

列印出以“:”為域分隔符中第4域小于30000的記錄中的第1域和第二域

$ awk -f: '{if($4<300000) print $1,$2}' employee2 

marry adams 5436

列印出以“:”為域分隔符中第4域大于350000 且小于 550000的記錄

$ awk -f: '{if(350000<$4 && $4<550000) print $0}' employee2 

列印出以“:”為域分隔符中第2域和第4域之和的平均值小于270000的記錄

$ awk -f: '{if(($2+$4)/2<270000) print $0}' employee2 

應用wage這個自定義變量,列印出以“:”為域分隔符且第一域包含“tom"關鍵字的第2域和第4域之和

$ awk -f: '{wage=$2+$4}{if($1~/tom/) print wage}' employee2 

547786

找出以“:”為域分隔符且第二域等于4432的記錄,并把第2域指派為1111進行列印

[czmmiao@czmmiao txt]$  awk -f: '$2 == 4432 { $2 = 1111;print}' employees2

tom jones 1111 5/12/66 543354

找出以“:”為域分隔符且第一域等于sally chang的記錄,列印出記錄行号,第1域,第2域和最後一個域。這裡注意,如果不加“ ”那麼,awk會比對空字元串結果如下

$ awk -f: '{if($1=="sally chang") print nr,$1,$2,nf}' employee2 

3 sally chang 1655 4

設定以“:”為域分隔符,制表符(\t)為,兩個回車為記錄分隔符,列印第1域,第2域,第3域

$ awk 'begin{fs=":";ofs="\t";ors="\n\n"}{print $1,$2,$3}' employee2 

tom jones       4432    5/12/66

marry adams     5436    11/4/63

sally chang     1655    7/22/54

billy black     1683    9/23/44

找出以“:”為域分隔符,列印記錄中包含"sally chang"的記錄号,第1域,第2域和最後一域。其中ignorecase=1參數表示忽略大小寫,這樣"sally chang" 能夠比對"sally chang"

$ awk -f: 'begin{ignorecase=1}{if($1=="sally chang") print nr,$1,$2,$nf}' employee2 

3 sally chang 1655 650000

列印“make year"跟在begin後的語句先執行,即使沒有輸入檔案,awk仍然執行begin後的語句

$ awk 'begin{print "make year"}'

make year

列印“the number of records is "記錄号,跟在end後的語句最後執行。(下例展現得更明顯。。。。。)

$ awk 'end{print "the number of records is "nr}' employees2

the number of records is 4

查找包含marry的字段,每查找到一個自定義變量+1最後執行列印“marry was found",變量count, "times."

$ awk '/marry/{count++}end{print "marry was found " count " times."}' employees2

marry was found 1 times.

參考至:《unix® shells by example fourth edition》by ellie quigley 

                  《linux與unix shell程式設計指南》

                 http://blog.sina.com.cn/s/blog_45b28bfb0100o0fs.html

本文為原創文章,轉載請注明出處、作者

如有錯誤,歡迎指正

郵箱: [email protected]

作者:czmmiao 原文位址:http://czmmiao.iteye.com/blog/939160

繼續閱讀