亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1290 | 回復(fù): 0
打印 上一主題 下一主題

grep sed awk 使用技巧 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2008-08-14 22:15 |只看該作者 |倒序瀏覽
【轉(zhuǎn)】
http://blog.tairan.org/2008/06/grep-sed-awk.html
Grep的常用命令語法1. 雙引號引用和單引號引用
在g r e p命令中輸入字符串參數(shù)時,最好將其用雙引號括起來。例如:”m y s t r i n g”。這樣做有兩個原因,一是以防被誤解為 s h e l l命令,二是可以用來查找多個單詞組成的字符串,例如:”jet plane”,如果不用雙引號將其括起來,那么單詞 p l a n e將被誤認為是一個文件,查詢結(jié)果將返回”文件不存在”的錯誤信息。
在調(diào)用變量時,也應(yīng)該使用雙引號,諸如: g r e p”$ M Y VA R”文件名,如果不這樣,將
沒有返回結(jié)果。
在調(diào)用模式匹配時,應(yīng)使用單引號.[root@mypc ]# echo `grep 123 111.txt` (#注意是反單引號)
2. 常用的g r e p選項有:
-c 只輸出匹配行的計數(shù)。
-i 不區(qū)分大小寫(只適用于單字符)。
-h 查詢多文件時不顯示文件名。
-l 查詢多文件時只輸出包含匹配字符的文件名。
-n 顯示匹配行及行號。
-s 不顯示不存在或無匹配文本的錯誤信息。
-v 顯示不包含匹配文本的所有行。
3. 特殊的–在多個文件中進行查詢
$ grep “sort”*.doc ( #在當(dāng)前目錄下所有. d o c文件中查找字符串”s o r t”)
$ grep “sort it” * (#或在所有文件中查詢單詞”sort it”)
接下來的所有示例是指在單個文件中進行查詢
4. 行匹配
$ grep -c “48″ data.f
$ 4 (#g r e p返回數(shù)字4,意義是有4行包含字符串”4 8″。)
$ grep “48″ data.f (#顯示包含”4 8″字符串的4行文本)
5. 顯示滿足匹配模式的所有行行數(shù):
[root@mypc oid2000]# grep -n 1234 111.txt
1:1234
3:1234ab
6. 精確匹配
[root@mypc oid2000]# grep “1234\>” 111.txt
1234
7. 查詢空行,查詢以某個條件開頭或者結(jié)尾的行。
結(jié)合使用^和$可查詢空行。使用- n參數(shù)顯示實際行數(shù)
[root@mypc oid2000]# grep -n “^$” 111.txt (返回結(jié)果 2: #說明第二行是空行)
[root@mypc oid2000]# grep -n “^abc” 111.txt (#查詢以abc開頭的行)
[root@mypc oid2000]# grep -n “abc$” 111.txt (#查詢以abc結(jié)尾的行)
8. 匹配特殊字符,查詢有特殊含義的字符,諸如$ . ‘ ” * [] ^ | \ + ? ,必須在特定字符前加\。
[root@mypc oid2000]# grep “\.” 111.txt (#在111.txt中查詢包含”.”的所有行)
[root@mypc oid2000]# grep “my\.conf” 111.txt (#查詢有文件名my. c o n f的行)
9. 目錄的查詢
[root@mypc oid2000]# ls -l |grep “^d” (#如果要查詢目錄列表中的目錄)
[root@mypc oid2000]# ls -l |grep “^d[d]” (#在一個目錄中查詢不包含目錄的所有文件)
[root@mypc]# ls -l |grpe “^d…..x..x” (#查詢其他用戶和用戶組成員有可執(zhí)行權(quán)限的目錄集合)
Awk的常用命令語法
awk命令擅長格式化報文或從一個大的文本文件中抽取數(shù)據(jù)包,下面是該命令的基本語法
awk [-F filed-separator] “commands” input-file(s)
[ - F域分隔符]是可選的,a w k使用空格作為缺省的域分隔符,如果在要處理的文件中是以冒號作為分割域的(如passwd文件),則在處理的時候要這樣指明 awk -F: command input-file(s)
1.1域和記錄
a w k執(zhí)行時,其瀏覽域標(biāo)記為$ 1,$ 2 . . . $ n。這種方法稱為域標(biāo)識。使用$ 1 , $ 3表示參照第1和第3域,注意這里用逗號做域分隔。如果希望打印一個有 5個域的記錄的所有域,不必指明 $ 1 , $ 2 , $ 3 , $ 4 , $ 5,可使用$ 0,意即所有域。
1.2保存a w k輸出
$ awk ‘{print $0}’ input-files > out-files (#重定向保存輸出)
$ awk ‘{print $0}’ input-files | tee out-files (#使用t e e命令,輸出到文件的同時輸出到屏幕)
1.3 常用的awk命令舉例
[root@mypc /]# awk ‘$0 ~ /user/’ /etc/passwd (#如果某域含有user就將該行打印出來)
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
[root@mypc /]# awk ‘/user/’ /etc/passwd (#同上)
[root@mypc /]# awk -F: ‘{if ($5 ~ /user/) print $0}’ /etc/passwd (#如第五域有user則輸出該行)
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
[root@mypc /]# ifconfig | awk ‘/inet/{print $2}’ (#從ifconfig的輸出中抽取含inet的行并打印第二域)
[root@mypc /]# ifconfig | awk ‘/inet/{print $2}’ | awk -F: ‘{print $2}’ (#在上面的基礎(chǔ)上再抽取,這個命令可以讓你直接得到本機的ip地址)
Sed的常用命令語法
Sed是一個非交互性文本流編輯器。它編輯文件或標(biāo)準(zhǔn)輸入導(dǎo)出的文本拷貝。
1.行的匹配
[root@mypc /]# sed -n ‘2p’ /etc/passwd 打印出第2行
[root@mypc /]# sed -n ‘1,3p’ /etc/passwd 打印出第1到第3行
[root@mypc /]# sed -n ‘$p’ /etc/passwd 打印出最后一行
[root@mypc /]# sed -n ‘/user/’p /etc/passwd 打印出含有user的行
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
[root@mypc /]# sed -n ‘/\$/’p /etc/passwd 打印出含有$元字符的行,$意為最后一行
2.插入文本和附加文本(插入新行)
[root@mypc /]# sed -n ‘/FTP/p’ /etc/passwd 打印出有FTP的行
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@mypc /]# sed ‘/FTP/ a\ 456′ /etc/passwd 在含有FTP的行后面新插入一行,內(nèi)容為456
[root@mypc /]# sed ‘/FTP/ i\ 123′ /etc/passwd在含有FTP的行前面新插入一行,內(nèi)容為123
[root@mypc /]# sed ‘/FTP/ i\ “123″‘ /etc/passwd在含有FTP的行前面新插入一行,內(nèi)容為”123″
[root@mypc /]# sed ‘5 a\ 123′ /etc/passwd 在第5行后插入一新行,內(nèi)容為123
[root@mypc /]# sed ‘5 i\ “12345″‘ /etc/passwd 在第5行前插入一新行,內(nèi)容為”12345″
3.刪除文本
[root@mypc /]# sed ‘1d’ /etc/passwd 刪除第1行
[root@mypc /]# sed ‘1,3d’ /etc/passwd 刪除第1至3行
[root@mypc /]# sed ‘/user/d’ /etc/passwd 刪除帶有user的行
4. 替換文本,替換命令用替換模式替換指定模式,格式為:
[ a d d r e s s [,address]] s/ pattern-to-find /replacement-pattern/[g p w n]
[root@mypc /]# sed ’s/user/USER/’ /etc/passwd 將第1個user替換成USER,g表明全局替換
[root@mypc /]# sed ’s/user/USER/g’ /etc/passwd 將所有user替換成USER
[root@mypc /]# sed ’s/user/#user/’ /etc/passwd 將第1個user替換成#user,如用于屏蔽作用
[root@mypc /]# sed ’s/user//’ /etc/passwd 將第1個user替換成空
[root@mypc /]# sed ’s/user/&11111111111111/’ /etc/passwd 如果要附加或修改一個很長的字符串,可以使用( &)命令,&命令保存發(fā)現(xiàn)模式以便重新調(diào)用它,然后把它放在替換字符串里面,這里是把&放前面
[root@mypc /]# sed ’s/user/11111111111111&/’ /etc/passwd 這里是將&放后面
5. 快速一行命令
下面是一些一行命令集。([ ]表示空格,[ ]表示t a b鍵)
‘s / \ . $ / / g’ 刪除以句點結(jié)尾行
‘-e /abcd/d’ 刪除包含a b c d的行
‘s / [ ] [ ] [ ] * / [ ] / g’ 刪除一個以上空格,用一個空格代替
‘s / ^ [ ] [ ] * / / g’ 刪除行首空格
‘s / \ . [ ] [ ] * / [ ] / g’ 刪除句點后跟兩個或更多空格,代之以一個空格
‘/ ^ $ / d’ 刪除空行
‘s / ^ . / / g’ 刪除第一個字符
‘s /COL \ ( . . . \ ) / / g’ 刪除緊跟C O L的后三個字母
‘s / ^ \ / / / g’ 從路徑中刪除第一個\
‘s / [ ] / [ ] / / g’ 刪除所有空格并用t a b鍵替代
‘S / ^ [ ] / / g’ 刪除行首所有t a b鍵
‘s / [ ] * / / g’ 刪除所有t a b鍵
如果使用s e d對文件進行過濾,最好將問題分成幾步,分步執(zhí)行,且邊執(zhí)行邊測試結(jié)果。
經(jīng)驗告訴我們,這是執(zhí)行一個復(fù)雜任務(wù)的最有效方式。
----------------------------------------------------------------------
什么是awk?
你可能對UNIX比較熟悉,但你可能對awk很陌生,這一點也不奇怪,的確,與其優(yōu)秀的功能相比,awk還遠沒達到它應(yīng)有的知名度。awk是什么?與其它大多數(shù)UNIX命令不同的是,從名字上看,我們不可能知道awk的功能:它既不是具有獨立意義的英文單詞,也不是幾個相關(guān)單詞的縮寫。事實上,awk是三個人名的縮寫,他們是:Aho、(Peter)Weinberg和(Brain)Kernighan。正是這三個人創(chuàng)造了awk---一個優(yōu)秀的樣式掃描與處理工具。
AWK的功能是什么?與sed和grep很相似,awk是一種樣式掃描與處理工具。但其功能卻大大強于sed和grep。awk提供了極其強大的功能:它幾乎可以完成grep和sed所能完成的全部工作,同時,它還可以可以進行樣式裝入、流控制、數(shù)學(xué)運算符、進程控制語句甚至于內(nèi)置的變量和函數(shù)。它具備了一個完整的語言所應(yīng)具有的幾乎所有精美特性。實際上,awk的確擁有自己的語言:awk程序設(shè)計語言,awk的三位創(chuàng)建者已將它正式定義為:樣式掃描和處理語言。
為什么使用awk?
即使如此,你也許仍然會問,我為什么要使用awk?
使用awk的第一個理由是基于文本的樣式掃描和處理是我們經(jīng)常做的工作,awk所做的工作有些象數(shù)據(jù)庫,但與數(shù)據(jù)庫不同的是,它處理的是文本文件,這些文件沒有專門的存儲格式,普通的人們就能編輯、閱讀、理解和處理它們。而數(shù)據(jù)庫文件往往具有特殊的存儲格式,這使得它們必須用數(shù)據(jù)庫處理程序來處理它們。既然這種類似于數(shù)據(jù)庫的處理工作我們經(jīng)常會遇到,我們就應(yīng)當(dāng)找到處理它們的簡便易行的方法,UNIX有很多這方面的工具,例如sed 、grep、sort以及find等等,awk是其中十分優(yōu)秀的一種。
使用awk的第二個理由是awk是一個簡單的工具,當(dāng)然這是相對于其強大的功能來說的。的確,UNIX有許多優(yōu)秀的工具,例如UNIX天然的開發(fā)工具C語言及其延續(xù)C++就非常的優(yōu)秀。但相對于它們來說,awk完成同樣的功能要方便和簡捷得多。這首先是因為awk提供了適應(yīng)多種需要的解決方案:從解決簡單問題的awk命令行到復(fù)雜而精巧的awk程序設(shè)計語言,這樣做的好處是,你可以不必用復(fù)雜的方法去解決本來很簡單的問題。例如,你可以用一個命令行解決簡單的問題,而C不行,即使一個再簡單的程序,C語言也必須經(jīng)過編寫、編譯的全過程。其次,awk本身是解釋執(zhí)行的,這就使得awk程序不必經(jīng)過編譯的過程,同時,這也使得它與shell script程序能夠很好的契合。最后,awk本身較C語言簡單,雖然awk吸收了C語言很多優(yōu)秀的成分,熟悉C語言會對學(xué)習(xí)awk有很大的幫助,但awk本身不須要會使用C語言——一種功能強大但需要大量時間學(xué)習(xí)才能掌握其技巧的開發(fā)工具。
使用awk的第三個理由是awk是一個容易獲得的工具。與C和C++語言不同,awk只有一個文件(/bin/awk),而且?guī)缀趺總版本的UNIX都提供各自版本的awk,你完全不必費心去想如何獲得awk。但C語言卻不是這樣,雖然C語言是UNIX天然的開發(fā)工具,但這個開發(fā)工具卻是單獨發(fā)行的,換言之,你必須為你的UNIX版本的C語言開發(fā)工具單獨付費(當(dāng)然使用D版者除外),獲得并安裝它,然后你才可以使用它。
基于以上理由,再加上awk強大的功能,我們有理由說,如果你要處理與文本樣式掃描相關(guān)的工作,awk應(yīng)該是你的第一選擇。在這里有一個可遵循的一般原則:如果你用普通的shell工具或shell script有困難的話,試試awk,如果awk仍不能解決問題,則便用C語言,如果C語言仍然失敗,則移至C++。
awk的調(diào)用方式
前面曾經(jīng)說過,awk提供了適應(yīng)多種需要的不同解決方案,它們是:
一、awk命令行,你可以象使用普通UNIX命令一樣使用awk,在命令行中你也可以使用awk程序設(shè)計語言,雖然awk支持多行的錄入,但是錄入長長的命令行并保證其正確無誤卻是一件令人頭疼的事,因此,這種方法一般只用于解決簡單的問題。當(dāng)然,你也可以在shell script程序中引用awk命令行甚至awk程序腳本。
二、使用-f選項調(diào)用awk程序。awk允許將一段awk程序?qū)懭胍粋文本文件,然后在awk命令行中用-f選項調(diào)用并執(zhí)行這段程序。具體的方法我們將在后面的awk語法中講到。
三、利用命令解釋器調(diào)用awk程序:利用UNIX支持的命令解釋器功能,我們可以將一段awk程序?qū)懭胛谋疚募,然后在它的第一行加?
#!/bin/awk -f
并賦予這個文本文件以執(zhí)行的權(quán)限。這樣做之后,你就可以在命令行中用類似于下面這樣的方式調(diào)用并執(zhí)行這段awk程序了。
$awk腳本文本名 待處理文件
awk的語法:
與其它UNIX命令一樣,awk擁有自己的語法:
awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]
參數(shù)說明:
-F re:允許awk更改其字段分隔符。
parameter: 該參數(shù)幫助為不同的變量賦值。
'prog': awk的程序語句段。這個語句段必須用單拓號:'和'括起,以防被shell解釋。這個程序語句段的標(biāo)準(zhǔn)形式為:
'pattern {action}'
其中pattern參數(shù)可以是egrep正則表達式中的任何一個,它可以使用語法/re/再加上一些樣式匹配技巧構(gòu)成。與sed類似,你也可以使用","分開兩樣式以選擇某個范圍。關(guān)于匹配的細節(jié),你可以參考附錄,如果仍不懂的話,找本UNIX書學(xué)學(xué)grep和sed(本人是在學(xué)習(xí)ed時掌握匹配技術(shù)的)。action參數(shù)總是被大括號包圍,它由一系統(tǒng)awk語句組成,各語句之間用";"分隔。awk解釋它們,并在pattern給定的樣式匹配的記錄上執(zhí)行其操作。與shell類似,你也可以使用“#”作為注釋符,它使“#”到行尾的內(nèi)容成為注釋,在解釋執(zhí)行時,它們將被忽略。你可以省略pattern和action之一,但不能兩者同時省略,當(dāng)省略pattern時沒有樣式匹配,表示對所有行(記錄)均執(zhí)行操作,省略action時執(zhí)行缺省的操作——在標(biāo)準(zhǔn)輸出上顯示。
-f progfile:允許awk調(diào)用并執(zhí)行progfile指定有程序文件。progfile是一個文本文件,他必須符合awk的語法。
in_file:awk的輸入文件,awk允許對多個輸入文件進行處理。值得注意的是awk不修改輸入文件。如果未指定輸入文件,awk將接受標(biāo)準(zhǔn)輸入,并將結(jié)果顯示在標(biāo)準(zhǔn)輸出上。awk支持輸入輸出重定向。
awk的記錄、字段與內(nèi)置變量:
前面說過,awk處理的工作與數(shù)據(jù)庫的處理方式有相同之處,其相同處之一就是awk支持對記錄和字段的處理,其中對字段的處理是grep和sed不能實現(xiàn)的,這也是awk優(yōu)于二者的原因之一。在awk中,缺省的情況下總是將文本文件中的一行視為一個記錄,而將一行中的某一部分作為記錄中的一個字段。為了操作這些不同的字段,awk借用shell的方法,用$1,$2,$3...這樣的方式來順序地表示行(記錄)中的不同字段。特殊地,awk用$0表示整個行(記錄)。不同的字段之間是用稱作分隔符的字符分隔開的。系統(tǒng)默認的分隔符是空格。awk允許在命令行中用-F re的形式來改變這個分隔符。事實上,awk用一個內(nèi)置的變量FS來記憶這個分隔符。awk中有好幾個這樣的內(nèi)置變量,例如,記錄分隔符變量RS、當(dāng)前工作的記錄數(shù)NR等等,本文后面的附表列出了全部的內(nèi)置變量。這些內(nèi)置的變量可以在awk程序中引用或修改,例如,你可以利用NR變量在模式匹配中指定工作范圍,也可以通過修改記錄分隔符RS讓一個特殊字符而不是換行符作為記錄的分隔符。
例:顯示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段:
awk -F % 'NR==7,NR==15 {printf $1 $3 $7}'
awk的內(nèi)置函數(shù)
awk之所以成為一種優(yōu)秀的程序設(shè)計語言的原因之一是它吸收了某些優(yōu)秀的程序設(shè)計語言(例如C)語言的許多優(yōu)點。這些優(yōu)點之一就是內(nèi)置函數(shù)的使用,awk定義并支持了一系列的內(nèi)置函數(shù),由于這些函數(shù)的使用,使得awk提供的功能更為完善和強大,例如,awk使用了一系列的字符串處理內(nèi)置函數(shù)(這些函數(shù)看起來與C語言的字符串處理函數(shù)相似,其使用方式與C語言中的函數(shù)也相差無幾),正是由于這些內(nèi)置函數(shù)的使用,使awk處理字符串的功能更加強大。本文后面的附錄中列有一般的awk所提供的內(nèi)置函數(shù),這些內(nèi)置函數(shù)也許與你的awk版本有些出入,因此,在使用之前,最好參考一下你的系統(tǒng)中的聯(lián)機幫助。
作為內(nèi)置函數(shù)的一個例子,我們將在這里介紹awk的printf函數(shù),這個函數(shù)使得awk與c語言的輸出相一致。實際上,awk中有許多引用形式都是從C語言借用過來的。如果你熟悉C語言,你也許會記得其中的printf函數(shù),它提供的強大格式輸出功能曾經(jīng)帶我們許多的方便。幸運的是,我們在awk中又和它重逢了。awk中printf幾乎與C語言中一模一樣,如果你熟悉C語言的話,你完全可以照C語言的模式使用awk中的printf。因此在這里,我們只給出一個例子,如果你不熟悉的話,請隨便找一本C語言的入門書翻翻。
例:顯示文件myfile中的行號和第3字段:
$awk '{printf"%03d%s\n",NR,$1}' myfile
在命令行使用awk
按照順序,我們應(yīng)當(dāng)講解awk程序設(shè)計的內(nèi)容了,但在講解之前,我們將用一些例子來對前面的知識進行回顧,這些例子都是在命令行中使用的,由此我們可以知道在命令行中使用awk是多么的方便。這樣做的原因一方面是為下面的內(nèi)容作鋪墊,另一方面是介紹一些解決簡單問題的方法,我們完全沒有必要用復(fù)雜的方法來解決簡單的問題----既然awk提供了較為簡單的方法的話。
例:顯示文本文件mydoc匹配(含有)字符串"sun"的所有行。
$awk '/sun/{print}' mydoc
由于顯示整個記錄(全行)是awk的缺省動作,因此可以省略action項。
$awk '/sun/' mydoc
例:下面是一個較為復(fù)雜的匹配的示例:
$awk '/[Ss]un/,/[Mm]oon/ {print}' myfile
它將顯示第一個匹配Sun或sun的行與第一個匹配Moon或moon的行之間的行,并顯示到標(biāo)準(zhǔn)輸出上。
例:下面的示例顯示了內(nèi)置變量和內(nèi)置函數(shù)length()的使用:
$awk 'length($0)>80 {print NR}' myfile
該命令行將顯示文本myfile中所有超過80個字符的行號,在這里,用$0表示整個記錄(行),同時,內(nèi)置變量NR不使用標(biāo)志符'$'。
例:作為一個較為實際的例子,我們假設(shè)要對UNIX中的用戶進行安全性檢查,方法是考察/etc下的passwd文件,檢查其中的passwd字段(第二字段)是否為"*",如不為"*",則表示該用戶沒有設(shè)置密碼,顯示出這些用戶名(第一字段)。我們可以用如下語句實現(xiàn):
#awk -F: '$2=="" {printf("%s no password!\n",$1' /etc/passwd
在這個示例中,passwd文件的字段分隔符是“:”,因此,必須用-F:來更改默認的字段分隔符,這個示例中也涉及到了內(nèi)置函數(shù)printf的使用。
awk的變量
如同其它程序設(shè)計語言一樣,awk允許在程序語言中設(shè)置變量,事實上,提供變量的功能是程序設(shè)計語言的其本要求,不提供變量的程序設(shè)計語言本人還從未見過。
awk提供兩種變量,一種是awk內(nèi)置的變量,這前面我們已經(jīng)講過,需要著重指出的是,與后面提到的其它變量不同的是,在awk程序中引用內(nèi)置變量不需要使用標(biāo)志符"$"(回憶一下前面講過的NR的使用)。awk提供的另一種變量是自定義變量。awk允許用戶在awk程序語句中定義并調(diào)用自已的變量。當(dāng)然這種變量不能與內(nèi)置變量及其它awk保留字相同,在awk中引用自定義變量必須在它前面加上標(biāo)志符"$"。與C語言不同的是,awk中不需要對變量進行初始化,awk根據(jù)其在awk中第一次出現(xiàn)的形式和上下文確定其具體的數(shù)據(jù)類型。當(dāng)變量類型不確定時,awk默認其為字符串類型。這里有一個技巧:如果你要讓你的awk程序知道你所使用的變量的明確類型,你應(yīng)當(dāng)在在程序中給它賦初值。在后面的實例中,我們將用到這一技巧。
作為一種程序設(shè)計語言所應(yīng)具有的特點之一,awk支持多種運算,這些運算與C語言提供的幾本相同:如+、-、*、/、%等等,同時,awk也支持C語言中類似++、--、+=、-=、=+、=-之類的功能,這給熟悉C語言的使用者編寫awk程序帶來了極大的方便。作為對運算功能的一種擴展,awk還提供了一系列內(nèi)置的運算函數(shù)(如log、sqr、cos、sin等等)和一些用于對字符串進行操作(運算)的函數(shù)(如length、substr等等)。這些函數(shù)的引用大大的提高了awk的運算功能。
作為對條件轉(zhuǎn)移指令的一部分,關(guān)系判斷是每種程序設(shè)計語言都具備的功能,awk也不例外。awk中允許進行多種測試,如常用的==(等于)、!=(不等于)、>(大于)、=(大于等于)、>=(小于等于)等等,同時,作為樣式匹配,還提供了~(匹配于)和!~(不匹配于)判斷。
作為對測試的一種擴充,awk也支持用邏輯運算符:!(非)、&&(與)、||(或)和括號()進行多重判斷,這大大增強了awk的功能。本文的附錄中列出了awk所允許的運算、判斷以及操作符的優(yōu)先級。
awk的流程控制
流程控制語句是任何程序設(shè)計語言都不能缺少的部分。任何好的語言都有一些執(zhí)行流程控制的語句。awk提供的完備的流程控制語句類似于C語言,這給我們編程帶來了極大的方便。
1、BEGIN和END:
在awk中兩個特別的表達式,BEGIN和END,這兩者都可用于pattern中(參考前面的awk語法),提供BEGIN和END的作用是給程序賦予初始狀態(tài)和在程序結(jié)束之后執(zhí)行一些掃尾的工作。任何在BEGIN之后列出的操作(在{}內(nèi))將在awk開始掃描輸入之前執(zhí)行,而END之后列出的操作將在掃描完全部的輸入之后執(zhí)行。因此,通常使用BEGIN來顯示變量和預(yù)置(初始化)變量,使用END來輸出最終結(jié)果。
例:累計銷售文件xs中的銷售金額(假設(shè)銷售金額在記錄的第三字段):
$awk
>'BEGIN { FS=":";print "統(tǒng)計銷售金額";total=0}
>{print $3;total=total+$3;}
>END {printf "銷售金額總計:%.2f",total}' sx
(注:>是shell提供的第二提示符,如要在shell程序awk語句和awk語言中換行,則需在行尾加反斜杠\)
在這里,BEGIN預(yù)置了內(nèi)部變量FS(字段分隔符)和自定義變量total,同時在掃描之前顯示出輸出行頭。而END則在掃描完成后打印出總合計。
2、流程控制語句
awk提供了完備的流程控制語句,其用法與C語言類似。下面我們一一加以說明:
2.1、if...else語句:
格式:
if(表達式)
語句1
else
語句2
格式中"語句1"可以是多個語句,如果你為了方便awk判斷也方便你自已閱讀,你最好將多個語句用{}括起來。awk分枝結(jié)構(gòu)允許嵌套,其格式為:
if(表達式1)
{if(表達式2)
語句1
else
語句2
}
語句3
else {if(表達式3)
語句4
else
語句5
}
語句6
當(dāng)然實際操作過程中你可能不會用到如此復(fù)雜的分枝結(jié)構(gòu),這里只是為了給出其樣式罷了。
2.2、while語句
格式為:
while(表達式)
語句
2.3、do-while語句
格式為:
do
{
語句
}while(條件判斷語句)
2.4、for語句
格式為:
for(初始表達式;終止條件;步長表達式)
{語句}
在awk的 while、do-while和for語句中允許使用break,continue語句來控制流程走向,也允許使用exit這樣的語句來退出。break中斷當(dāng)前正在執(zhí)行的循環(huán)并跳到循環(huán)外執(zhí)行下一條語句。continue從當(dāng)前位置跳到循環(huán)開始處執(zhí)行。對于exit的執(zhí)行有兩種情況:當(dāng)exit語句不在END中時,任何操作中的exit命令表現(xiàn)得如同到了文件尾,所有模式或操作執(zhí)行將停止,END模式中的操作被執(zhí)行。而出現(xiàn)在END中的exit將導(dǎo)致程序終止。
例:為了
awk中的自定義函數(shù)
定義和調(diào)用用戶自己的函數(shù)是幾乎每個高級語言都具有的功能,awk也不例外,但原始的awk并不提供函數(shù)功能,只有在nawk或較新的awk版本中才可以增加函數(shù)。
函數(shù)的使用包含兩部分:函數(shù)的定義與函數(shù)調(diào)用。其中函數(shù)定義又包括要執(zhí)行的代碼(函數(shù)本身)和從主程序代碼傳遞到該函數(shù)的臨時調(diào)用。
awk函數(shù)的定義方法如下:
function 函數(shù)名(參數(shù)表){
函數(shù)體
}
在gawk中允許將function省略為func,但其它版本的awk不允許。函數(shù)名必須是一個合法的標(biāo)志符,參數(shù)表中可以不提供參數(shù)(但在調(diào)用函數(shù)時函數(shù)名后的一對括號仍然是不可缺少的),也可以提供一個或多個參數(shù)。與C語言相似,awk的參數(shù)也是通過值來傳遞的。
在awk中調(diào)用函數(shù)比較簡單,其方法與C語言相似,但awk比C語言更為靈活,它不執(zhí)行參數(shù)有效性檢查。換句話說,在你調(diào)用函數(shù)時,可以列出比函數(shù)預(yù)計(函數(shù)定義中規(guī)定)的多或少的參數(shù),多余的參數(shù)會被awk所忽略,而不足的參數(shù),awk將它們置為缺省值0或空字符串,具體置為何值,將取決于參數(shù)的使用方式。
awk函數(shù)有兩種返回方式:隱式返回和顯式返回。當(dāng)awk執(zhí)行到函數(shù)的結(jié)尾時,它自動地返回到調(diào)用程序,這是函數(shù)是隱式返回的。如果需要在結(jié)束之前退出函數(shù),可以明確地使用返回語句提前退出。方法是在函數(shù)中使用形如:return 返回值 格式的語句。
例:下面的例子演示了函數(shù)的使用。在這個示例中,定義了一個名為print_header的函數(shù),該函數(shù)調(diào)用了兩個參數(shù)FileName和PageNum,F(xiàn)ileName參數(shù)傳給函數(shù)當(dāng)前使用的文件名,PageNum參數(shù)是當(dāng)前頁的頁號。這個函數(shù)的功能是打印(顯示)出當(dāng)前文件的文件名,和當(dāng)前頁的頁號。完成這個功能后,這個函數(shù)將返回下一頁的頁號。
nawk
>'BEGIN{pageno=1;file=FILENAME
>pageno=print_header(file,pageno);#調(diào)用函數(shù)print_header
>printf("當(dāng)前頁頁號是:%d\n",pageno);
>}
>#定義函數(shù)print_header
>function print_header(FileName,PageNum){
>printf("%s %d\n",FileName,PageNum); >PageNum++;return PageNUm;
>}
>}' myfile
執(zhí)行這個程序?qū)@示如下內(nèi)容:
myfile 1
當(dāng)前頁頁號是:2
awk高級輸入輸出
1.讀取下一條記錄:
awk的next語句導(dǎo)致awk讀取下一個記錄并完成模式匹配,然后立即執(zhí)行相應(yīng)的操作。通常它用匹配的模式執(zhí)行操作中的代碼。next導(dǎo)致這個記錄的任何額外匹配模式被忽略。
2.簡單地讀取一條記錄
awk的 getline語句用于簡單地讀取一條記錄。如果用戶有一個數(shù)據(jù)記錄類似兩個物理記錄,那么getline將尤其有用。它完成一般字段的分離(設(shè)置字段變量$0 FNR NF NR)。如果成功則返回1,失敗則返回0(到達文件尾)。如果需簡單地讀取一個文件,則可以編寫以下代碼:
例:示例getline的使用
{while(getline==1)
{
#process the inputted fields
}
}
也可以使getline保存輸入數(shù)據(jù)在一個字段中,而不是通過使用getline variable的形式處理一般字段。當(dāng)使用這種方式時,NF被置成0,F(xiàn)NR和NR被增值。
用戶也可以使用getline"datafile"

printf("hello word!\n")>>"datafile"
5.輸出到一個命令
awk中允許用如下方式將結(jié)果輸出到一個命令:
printf("hello word!\n")|"sort-t','"
awk與shell script混合編程
因為awk可以作為一個shell命令使用,因此awk能與shell批處理程序很好的融合在一起,這給實現(xiàn)awk與shell程序的混合編程提供了可能。實現(xiàn)混合編程的關(guān)鍵是awk與shell script之間的對話,換言之,就是awk與shell script之間的信息交流:awk從shell script中獲取所需的信息(通常是變量的值)、在awk中執(zhí)行shell命令行、shell script將命令執(zhí)行的結(jié)果送給awk處理以及shell script讀取awk的執(zhí)行結(jié)果等等。
1.awk讀取Shell script程序變量
在awk中我們可以通過“'$變量名'”的方式讀取sell scrpit程序中的變量。
例:在下面的示例中,我們將讀取sell scrpit程序中的變量Name,該變量存放的是文本myfile的撰寫者,awk將打印出這個人名。
$cat writename
:
# @(#)
#
.
.
.
Name="張三" nawk 'BEGIN {name="'Name'";\ printf("\t%s\t撰寫者%s\n",FILENAME,name");}\
{...}END{...}' myfile
.
.
.
2.將shell命令的執(zhí)行結(jié)果送給awk處理
作為信息傳送的一種方法,我們可以將一條shell命令的結(jié)果通過管道線(|)傳遞給awk處理:
例:示例awk處理shell命令的執(zhí)行結(jié)果
$who -u | awk '{printf("%s正在執(zhí)行%s\n",$2,$1)}'
該命令將打印出注冊終端正在執(zhí)行的程序名。
3.shell script程序讀awk的執(zhí)行結(jié)果
為了實現(xiàn)shell script程序讀取awk執(zhí)行的結(jié)果,我們可以采取一些特殊的方法,例如我們可以用變量名=`awk語句`的形式將awk執(zhí)行的結(jié)果存放入一個shell script變量。當(dāng)然也可以用管道線的方法將awk執(zhí)行結(jié)果傳遞給shell script程序處理。
例:作為傳送消息的機制之一,UNIX提供了一個向其所有用戶傳送消息的命令wall(意思是write to all寫給所有用戶),該命令允許向所有工作中的用戶(終端)發(fā)送消息。為此,我們可以通過一段shell批處理程序wall.shell來模擬這一程序(事實上比較老的版本中wall就是一段shell批處理程序:
$cat wall.shell
:
# @(#) wall.shell:發(fā)送消息給每個已注冊終端
#
cat >/tmp/$$
#用戶錄入消息文本 who -u | awk '{print $2}' | while read tty
do
cat /tmp/$$>$tty
done
在這個程序里,awk接受who -u命令的執(zhí)行結(jié)果,
該命令打印出所有已注冊終端的信息,其中第二個字段是已注冊終端的設(shè)備名,因此用awk命令析出該設(shè)備名,然后用while read tty語句循環(huán)讀出這些文件名到變量(shell script變量)tty中,作為信息傳送的終結(jié)地址。
4.在awk中執(zhí)行shell命令行----嵌入函數(shù)system()
system()是一個不適合字符或數(shù)字類型的嵌入函數(shù),該函數(shù)的功能是處理作為參數(shù)傳遞給它的字符串。system對這個參數(shù)的處理就是將其作為命令處理,也就是說將其當(dāng)作命令行一樣加以執(zhí)行。這使得用戶在自己的awk程序需要時可以靈活地執(zhí)行命令或腳本。
例:下面的程序?qū)⑹褂胹ystem嵌入函數(shù)打印用戶編制好的報表文件,這個文件存放在名為myreport.txt的文件中。為簡約起見,我們只列出了其END部分:
.
.
.
END {close("myreport.txt");system("lp myreport.txt");}
在這個示例中,我們首先使用close語句關(guān)閉了文件myreport.txt文件,然后使用system嵌入函數(shù)將myreport.txt送入打印機打印。
寫到這里,我不得不跟朋友們說再見了,實在地說,這些內(nèi)容仍然是awk的初步知識,電腦永遠是前進的科學(xué),awk也不例外,本篇所能做的只是在你前行的漫漫長途中鋪平一段小小開端,剩下的路還得靠你自己去走。老實說,如果本文真能給你前行的路上帶來些許的方便,那本人就知足了!
如對本篇有任何疑問,請E-mail To:Chizlong@yeah.net或到主頁http://chizling.yeah.net中留言。
附錄:
1.awk的常規(guī)表達式元字符
\ 換碼序列
^ 在字符串的開頭開始匹配
$ 在字符串的結(jié)尾開始匹配
. 與任何單個字符串匹配
[ABC] 與[]內(nèi)的任一字符匹配
[A-Ca-c] 與A-C及a-c范圍內(nèi)的字符匹配(按字母表順序)
[^ABC] 與除[]內(nèi)的所有字符以外的任一字符匹配
Desk|Chair 與Desk和Chair中的任一個匹配
[ABC][DEF] 關(guān)聯(lián)。與A、B、C中的任一字符匹配,且其后要跟D、E、F中的任一個字符。
* 與A、B或C中任一個出現(xiàn)0次或多次的字符相匹配
+ 與A、B或C中任何一個出現(xiàn)1次或多次的字符相匹配
? 與一個空串或A、B或C在任何一個字符相匹配
(Blue|Black)berry 合并常規(guī)表達式,與Blueberry或Blackberry相匹配
2.awk算術(shù)運算符
運算符 用途
------------------
x^y x的y次冪
x**y 同上
x%y 計算x/y的余數(shù)(求模)
x+y x加y
x-y x減y
x*y x乘y
x/y x除y
-y 負y(y的開關(guān)符號);也稱一目減
++y y加1后使用y(前置加)
y++ 使用y值后加1(后綴加)
--y y減1后使用y(前置減)
y-- 使用后y減1(后綴減)
x=y 將y的值賦給x
x+=y 將x+y的值賦給x
x-=y 將x-y的值賦給x
x*=y 將x*y的值賦給x
x/=y 將x/y的值賦給x x%=y 將x%y的值賦給x
x^=y 將x^y的值賦給x
x**=y 將x**y的值賦給x
3.awk允許的測試:
操作符 含義
x==y x等于y
x!=y x不等于y
x>y x大于y
x>=y x大于或等于y
x >=


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u1/53151/showart_1131098.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP