linux下的文字處理命令sed

mrhaozi發表於2009-12-10

linux下的文字處理命令sed&awk&grep
2007-03-14 15:53:46
Sed
sed 是個精簡的、非互動式的編輯器。他能執行和編輯vi和emacs相同的編輯任務。sed編輯器不提供互動使用方式:只能在命令列輸入編輯命令、指定檔案
名,然後在螢幕上察看輸出。sed編輯器沒有破壞性。他不會修改檔案,除非用shell重定向來儲存輸出結果。預設情況下,所以的輸出都被列印到螢幕上。
sed 編輯器在shell指令碼中非常有用,因為在shell指令碼中使用像vi或emacs這類互動式編輯器,需求指令碼使用者精通該編輯器,而且還會導致使用者對開啟的 檔案做出不必的修改。如果需要執行多項編輯任務,或是不想為shell命令列上的sed命令加引號,也能把sed命令寫在一個叫做sed指令碼的檔案
裡。記住,在命令列輸入命令時,shell會設法轉換命令中所有的元字元或空白。sed命令中凡是可能被shell解釋的字元都必須加引號進行保護。
sed 是一種線上編輯器,他一次處理一行內容。處理時,把當前處理的行儲存在臨時緩衝區中,稱為“模式空間”(pattern space),接著用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往螢幕。接著處理下一行,這樣不斷重複,直到檔案末尾。檔案內容並沒有
改動,除非你使用重定向儲存輸出。Sed主要用來自動編輯一個或多個檔案;簡化對檔案的反覆操作;編寫轉換程式等。以下介紹的是Gnu版本的Sed 3.02。
1. 定址功能
能透過定址來定位你所希望編輯的行,該地址用數字構成,用逗號分隔的兩個行數表示以這兩行為起止的行的範圍(包括行數表示的那兩行)。如1,3表示1,2,3行,美元符號($)表示最後一行。範圍能透過資料,正規表示式或二者結合的方式確定

2.sed命令呼叫格式
呼叫sed命令有兩種形式:
* sed [options] ’command’ file(s)
* sed [options] -f scrīptfile file(s)
a\ 在當前行後面加入一行文字。
b lable 分支到指令碼中帶有標記的地方,如果分支不存在則分支到指令碼的末尾。
c\ 用新的文字改動本行的文字。
d 從模板塊(Pattern space)位置刪除行。
D 刪除模板塊的第一行。
i\ 在當前行上面插入文字。
h 複製模板塊的內容到記憶體中的緩衝區。
H 追加模板塊的內容到記憶體中的緩衝區。
g 獲得記憶體緩衝區的內容,並替代當前模板塊中的文字。
G 獲得記憶體緩衝區的內容,並追加到當前模板塊文字的後面。
l 列表不能列印字元的清單。
n 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。
N 追加下一個輸入行到模板塊後面並在二者間嵌入一個新行,改動當前行號碼。
p 列印模板塊的行。
P(大寫) 列印模板塊的第一行。
q 退出Sed。
r file 從file中讀行。
t label if分支,從最後一行開始,條件一旦滿足或T,t命令,將導致分支到帶有標號的命令處,或到指令碼的末尾。
T label 錯誤分支,從最後一行開始,一旦發生錯誤或T,t命令,將導致分支到帶有標號的命令處,或到指令碼的末尾。
w file 寫並追加模板塊到file末尾。
W file 寫並追加模板塊的第一行到file末尾。
! 表示後面的命令對所有沒有被選定的行發生作用。
s/re/string 用string替換正規表示式re。
= 列印當前行號碼。
*把註釋擴充套件到下一個換行符以前。
以下的是替換標記
* g表示行內全方面替換。
* p表示列印行。
* w表示把行寫入一個檔案。
* x表示互換模板塊中的文字和緩衝區中的文字。
* y表示把一個字元翻譯為另外的字元(不過不用於正規表示式)
3. 選項 -e command, --expression=command
允許多臺編輯。
-h, --help 列印幫助,並顯示bug列表的地址。
-n, --quiet, --silent 取消預設輸出。
-f, --filer=scrīpt-file 引導sed指令碼檔名。
-V, --version 列印版本和版權資訊。
4. 元字符集
^ 錨定行的開始 如:/^sed/匹配所有以sed開頭的行。
$ 錨定行的結束 如:/sed$/匹配所有以sed結尾的行。
. 匹配一個非換行符的字元 如:/s.d/匹配s後接一個任意字元,然後是d。
* 匹配零或多個字元 如:/*sed/匹配所有模板是個或多個空格後緊跟sed的行。
[] 匹配一個指定範圍內的字元,如/[Ss]ed/匹配sed和Sed。
[^] 匹配一個不在指定範圍內的字元,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一個字母開頭,緊跟ed的行。
\(..\) 儲存匹配的字元,如s/\(love\)able/\1rs,loveable被替換成lovers。
& 儲存搜尋字元用來替換其他字元,如s/love/**&**/,love這成**love**。
\ 錨定單詞的結束,如/love\>/匹配包含以love結尾的單詞的行。 x\{m\} 重複字元x,m次,如:/0\{5\}/匹配包含5個o的行。
x\{m,\} 重複字元x,至少m次,如:/o\{5,\}/匹配至少有5個o的行。 x\{m,n\} 重複字元x,至少m次,不多於n次,如:/o\{5,10\}/匹配5--10個o的行。
5. 例項
5.1刪除:d命令
* $ sed ’2d’ example-----刪除example檔案的第二行。
* $ sed ’2,$d’
example-----刪除example檔案的第二行到末尾所有行。
* $ sed ’$d’ example-----刪除example檔案的最後一行。
* $ sed ’/test/’d
example-----刪除example檔案所有包含test的行。
5.2替換:s命令
* $ sed ’s/test/mytest/g’
example-----在整行範圍內把test替換為mytest。如果沒有g標記,則只有每行第一個匹配的test被替換成mytest。
* $ sed -n
’s/^test/mytest/p’ example-----(-n)選項和p標誌一起使用表示只列印那些發生替換的行。也就是說,如果某一行開頭的test被替換成mytest,就列印他。
* $ sed
’s/^192.168.0.1/&localhost/’ example-----&符號表示替換換字串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成他自已加
localhost,變成192.168.0.1localhost。
* $ sed -n
’s/\(love\)able/\1rs/p’ example-----love被標記為1,所有loveable會被替換成lovers,而且替換的行會被列印出來。
* $ sed ’s#10#100#g’
example-----不論什麼字元,緊跟著s命令的都被認為是新的分隔符,所以,“#”在這裡是分隔符,代替了預設的“/”分隔符。表示把所有10替換成100。
5.3選定行的範圍:逗號
* $ sed -n
’/test/,/check/p’ example-----所有在模板test和check所確定的範圍內的行都被列印。
* $ sed -n ’5,/^test/p’
example-----列印從第五行開始到第一個包含以test開始的行之間的所有行。
* $ sed
’/test/,/check/s/$/sed test/’ example-----對於模板test和west之間的行,每行的末尾用字串sed test替換。
5.4多點編輯:e命令
* $ sed -e ’1,5d’ -e
’s/test/check/’ example-----(-e)選項允許在同一行裡執行多條命令。如例子所示,第一條命令刪除1至5行,第二條命令用check替換test。命令的執
行順序對結果有影響。如果兩個命令都是替換命令,那麼第一個替換命令將影響第二個替換命令的結果。
* $ sed
--expression=’s/test/check/’ --expression=’/love/d’ example-----一個比-e更好的命令是--expression。他能給sed表示式賦值。
5.5從檔案讀入:r命令
* $ sed ’/test/r file’
example-----file裡的內容被讀進來,顯示在和test匹配的行後面,如果匹配多行,則file的內容將顯示在所有匹配行的下面。
5.6寫入檔案:w命令
* $ sed -n ’/test/w file’
example-----在example中所有包含test的行都被寫入file裡。
5.7追加命令:a命令
* $ sed
’/^test/a\\---&gtthis is a example’ example
awk
awk是一種程式語言,對檔案資料的處理具有非常強的功能。awk名稱是由他三個最初設計者的姓氏的第一個字母而命名的: Alfred V.
Aho、Peter J. We i n b e rg e r、Brian W. Kernighan。
awk 最初在1 9 7 7年完成。1985年發表了一個新版本的awk,他的功能比舊版本增強了不少。awk能夠用非常短的程式對檔案裡的資料做修改、比較、提取、列印等處理。如
果使用C 或Pascal等語言編寫程式完成上述的任務會十分不方便而且非常花費時間,所寫的程式也會非常大。
awk不僅僅是個程式語言,他還是
[url=javascript:;]linux[/url]
系統管理員和程式員的一個不可缺少的工具。
awk語言本身十分好學,易於掌控,並且特別的靈活。
gawk是G N U計劃下所做的awk,gawk最初在1 9 8 6年完成,之後不斷地被改進、更新。
gawk 包含awk 的所有功能。
1.gawk的主要功能
gawk 的主要功能是針對檔案的每一行( l i n e ),也就是每一條記錄,搜尋指定的格式。當某一行符合指定的格式時,gawk 就會在此行執行被指定的動作。gawk
依此方式自動處理輸入檔案的每一行直到輸入檔案檔案結束。
gawk經常用在如下的幾個方面:
• 根據需求選擇檔案的某幾行,幾列或部分欄位以供顯示輸出。
• 分析檔案中的某一個字出現的頻率、位置等。
• 根據某一個檔案的資訊準備格式化輸出。
• 以一個功能十分強大的方式過濾輸出檔案。
• 根據檔案中的數值進行計算。
2.怎麼執行gawk程式
基本上有兩種方法能執行gawk程式。
如果gawk 程式非常短,則能將gawk 直接寫在命令列,如下所示:
gawk ’program’ input-file1 input-file2 ...
其中program 包括一些pattern和action。
如果gawk 程式較長,較為方便的做法是將gawk 程式存在一個檔案中,
gawk 的格式如下所示:
gawk -f program-file input-file1 input-file2 ...
gawk 程式的檔案不止一個時,執行gawk 的格式如下所示:
gawk -f program-file1 -f program-file2 ... input-file1 input-file2 ...
3.檔案、記錄和欄位
一般情況下,gawk能處理檔案中的數值資料,但也能處理字串資訊。如果資料沒有儲存在檔案中,能透過管道命令和其他的重定向方法給gawk提供輸入。當然,
gawk只能處理文字檔案(A S C I I碼檔案)。
電話號碼本就是個gawk能處理的檔案的簡單例子。電話號碼本由非常多條目組成,每一個條目都有同樣的格式:姓、名、地址、電話號碼。每一個條目都是按字母順序排列。
在gawk中,每一個這樣的條目叫做一個記錄。他是個完整的資料的集合。例如,電話號碼本中的Smith John這個條目,包括他的地址和電話號碼,就是一條記錄。
記錄中的每一項叫做一個欄位。在gawk中,欄位是最基本的單位。多個記錄的集合組成了一個檔案。
大多數情況下,欄位之間由一個特別的字元分開,像空格、TAB、分號等。這些字元叫做欄位分隔符。請看下面這個/etc/passwd檔案:
tparker;t36s62hs;501;101;TimParker;/home/tparker;/bin/bash
etreijs;2ys639dj3;502;101;EdTreijs;/home/etreijs;/bin/tcsh
ychow;1h27sj;503;101;Yvonne Chow;/home/ychow;/bin/bash
你能看出/etc/passwd檔案使用分號作為欄位分隔符。/etc/passwd檔案中的每一行都包括七個欄位:使用者名稱;口令;使用者I D;工作組I D;註釋;
h o m e目錄;啟始的外殼。如果你想要查詢第六個欄位,只需數過五個分號即可。
但考慮到以下電話號碼本的例子,你就會發現一些問題:
Smith John 13 Wilson St. 555-1283
Smith John 2736 Artside Dr Apt 123 555-2736
Smith John 125 Westmount Cr 555-1726
雖 然我們能夠分辨出每個記錄包括四個欄位,但g a w k卻無能為力。電話號碼本使用空格作為分隔符,所以gawk認為Smith是第一個欄位,John是第二個欄位,13是第三個欄位,依次類推。就gawk
而言,如果用空格作為欄位分隔符的話,則第一個記錄有六個欄位,而第二個記錄有八個欄位。
所以,我們必須找出一個更好的欄位分隔符。例如,像下面相同使用斜槓作為欄位分隔符:
Smith/John/13 Wilson St./555-1283
Smith/John/2736 Artside Dr/Apt/123/555-2736
Smith/John/125 Westmount Cr/555-1726
如果你沒有指定其他的字元作為欄位分隔符,那麼gawk將預設地使用空格或TAB作為欄位分隔符。
4.模式和動作
在gawk語言中每一個命令都由兩部分組成:一個模式(pattern)和一個相應的動作
(action)。只要模式符合,gawk就會執行相應的動作。其中模式部分用兩個斜槓括起來,而動
作部分用一對花括號括起來。例如:
/pattern1/{action1}
/pattern2/{action2}
/pattern3/{action3}
所有的gawk程式都是由這樣的一對對的模式和動作組成的。其中模式或動作都能夠被省
略,不過兩個不能同時被省略。如果模式被省略,則對於作為輸入的檔案裡面的每一行,動作
都會被執行。如果動作被省略,則預設的動作被執行,既顯示出所有符合模式的輸入行而不做
所有的改動。
下面是個簡單的例子,因為gawk 程式非常短,所以將gawk 程式直接寫在外殼命令列:
gawk ’/tparker/’ /etc/passwd
此程式在上面提到的/etc/passwd 檔案中尋找符合tparker模式的記錄並顯示(此例中沒有動作,所以預設的動作被執行)。
讓我們再看一個例子:
gawk ’/UNIX/{print $2}’ file2.data
此命令將逐行查詢file2.data檔案中包含UNIX的記錄,並列印這些記錄的第二個欄位。
你也能在一個命令中使用多個模式和動作對,例如:
gawk ’/scandal/{print $1} /rumor/{print $2}’ gossip_file
此命令搜尋檔案gossip_file中包括scandal的記錄,並列印第一個欄位。然後再從頭搜尋
gossip_file中包括rumor的記錄,並列印第二個欄位。
5.比較運算和數值運算
gawk有非常多比較運算子,下面列出重要的幾個:
= = 相等
! = 不相等
> 大於
= 大於等於
100’ testfile
將會顯示檔案testfile 中那些第四個欄位大於1 0 0的記錄。
下表列出了gawk中基本的數值運算子。
運算子說明示例
+ 加法運算2+6
- 減法運算6-3
* 乘法運算2*5
/ 除法運算8/4
^ 乘方運算3^2 (=9)
% 求餘數9%4 (=1)
例如:
{print $3/2}
顯示第三個欄位被2除的結果。
在gawk中,運算子的優先權和一般的數學運算的優先權相同。例如:
{print $1+$2*$3}
顯示第二個欄位和第三個欄位相乘,然後和第一個欄位相加的結果。
你也能用括號改動優先次序。例如:
{print ($1+$2)*$3}
顯示第一個欄位和第二個欄位相加,然後和第三個欄位相乘的結果。
6.內部函式
gawk中有各種的內部函式,目前介紹如下:
6.1 隨機數和數學函式
sqrt(x) 求x 的平方根
sin(x) 求x 的正弦函式
cos(x) 求x 的餘弦函式
atan2(x,y) 求x / y的餘切函式
[url=javascript:;]log[/url]
(x) 求x 的自然對數
exp(x) 求x 的e 次方
int(x) 求x 的整數部分
rand() 求0 和1之間的隨機數
srand(x) 將x 設定為rand()的種子數
6.2 字串的內部函式
• index( in,find) 在字串in中尋找字串find 第一次出現的地方,返回值是字串
find 出目前字串in 裡面的位置。如果在字串in 裡面未找到字串find,則返回值為0。
例如:
print index("peanut"," a n " )
顯示結果3。
• length(string) 求出string 有幾個字元。
例如:
length("abcde")
顯示結果5。
• match(string,regexp) 在字串string 中尋找符合regexp的最長、最靠左邊的子字串。返回值是regexp 在string 的開始位置,即index值。match
函式將會設定系統變數
RSTART等於index的值,系統變數RLENGTH 等於符合的字元個數。如果不符合,則會
設定RSTART為0、RLENGTH 為- 1。
• sprintf( format,expression1,. . . ) 和printf 類似,不過sprintf 並不顯示,而是返回字串。
例如:
sprintf("pi = %.2f (approx.)",2 2 / 7 )
返回的字串為pi = 3.14 (approx.)
• s u b ( r e g e x p,r e p l a c e m e n t,t a rg e t ) 在字串t a rget 中尋找符合regexp
的最長、最靠左的
地方,以字串replacement 代替最左邊的r e g e x p。
例如:
str = "water,water,everywhere"
sub( /at/, "ith",str)
結果字串str會變成wither,water,everywhere
• gsub(regexp,replacement,target) 和前面的sub類似。在字串target 中尋找符合regexp的所有地方,以字串replacement
代替所有的regexp。
例如:
str = "water,water,everywhere"
gsub( /at/, "ith",str)
結果字串str會變成wither,wither,everywhere
• substr(string,start,length)返回字串string 的子字串,這個子字串的長度為length,從第start個位置開始。
例如:
substr("washington",5,3)
返回值為ing
如果沒有length,則返回的子字串是從第start 個位置開始至結束。
例如:
substr("washington",5)
返回值為ington。
• tolower(string) 將字串s t r i n g的大寫字母改為小寫字母。
例如:
tolower("MiXeD cAsE 123")
返回值為mixed case 123。
• toupper(string) 將字串s t r i n g的小寫字母改為大寫字母。
例如:
toupper("MiXeD cAsE 123")
返回值為MIXED CASE 123。
6.3 輸入輸出的內部函式
• close(filename) 將輸入或輸出的檔案filename 關閉。
• system(command) 此函式允許使用者執行
[url=javascript:;]作業系統[/url]
的指令,執行完畢後將回到gawk程式。
例如:
BEGIN {system("ls")}
7.字串和數字
字串就是一連串的字元,他能被gawk逐字地翻譯。字串用雙引號括起來。數字不能用雙引號括起來,並且gawk將他當作一個數值。例如:
gawk ’$1 != "Tim" {print}’ testfile
此命令將顯示第一個欄位和Tim不相同的所有記錄。如果命令中Tim兩邊不用雙引號,gawk將不能正確執行。
再如:
gawk ’$1 == "50" {print}’ testfile
此命令將顯示所有第一個欄位和5 0這個字串相同的記錄。g a w k不管第一欄位中的數值
的大小,而只是逐字地比較。這時,字串5 0和數值5 0並不相等。
8.格式化輸出
我們能讓動作顯示一些比較複雜的結果。例如:
gawk ’$1 != "Tim" {print $1,$ 5,$ 6,$2}’ testfile
將顯示testfile檔案中所有第一個欄位和Ti m不相同的記錄的第一、第五、第六和第二個欄位。
進一步,你能在p r i n t動作中加入字串,例如:
gawk ’$1 != "Tim" {print "The entry for ",$ 1,"is not
Tim. ",$2}’ testfile
print動作的每一部分用逗號隔開。
借用C語言的格式化輸出指令,能讓gawk的輸出形式更為多樣。這時,應該用printf而不是print。例如:
{printf "%5s likes this language\n",$ 2 }
printf中的%5s 部分告訴gawk怎麼格式化輸出字串,也就是輸出5個字元長。他的值由printf 的最後部分指出,在此是第二個欄位。\n是回車換行符。如果第二個欄位中儲存的是人名,則輸出結果大致如下:
Tim likes this language
Geoff likes this language
Mike likes this language
Joe likes this language
gawk 語言支援的其他格式控制符號如下:
• c 如果是字串,則顯示第一個字元;如果是整數,則將數字以ASCII 字元的形式顯示。
例如:
printf “% c”,65
結果將顯示字母A。
• d 顯示十進位制的整數。
• i 顯示十進位制的整數。
• e 將浮點數以科學記數法的形式顯示。
例如:
print “$ 4 . 3 e”,1950
結果將顯示1.950e+03。
• f 將數字以浮點的形式顯示。
• g 將數字以科學記數法的形式或浮點的形式顯示。數字的絕對值如果大於等於0 . 0 0 0 1則
以浮點的形式顯示,否則以科學記數法的形式顯示。
• o 顯示無符號的八進位制整數。
• s 顯示一個字串。
• x 顯示無符號的十六進位制整數。1 0至1 5以a至f表示。
• X 顯示無符號的十六進位制整數。1 0至1 5以A至F表示。
• % 他並不是真正的格式控制字元,% %將顯示%。
當你使用這些格式控制字元時,你能在控制字元前給出數字,以表示你將用的幾位或幾個字元。例如,6 d表示一個整數有6位。再請看下面的例子:
{printf "%5s works for %5s and earns %2d an hour",$1,$2,$3}
將會產生類似如下的輸出:
Joe works for Mike and earns 12 an hour
當處理資料時,你能指定資料的精確位數
{printf "%5s earns $%.2f an hour",$ 3,$ 6 }
其輸出將類似於:
Joe earns $12.17 an hour
你也能使用一些換碼控制符格式化整行的輸出。之所以叫做換碼控制符,是因為gawk對這些符號有特別的解釋。下面列出常用的換碼控制符:
\a 警告或響鈴字元。
\b 後退一格。
\f 換頁。
\n 換行。
\r 回車。
\t Ta b。
\v 垂直的t a b。
9.改動欄位分隔符
在g a w k中,預設的欄位分隔符一般是空格符或TA B。但你能在命令列使用- F選項改動字元分隔符,只需在- F後面跟著你想用的分隔符即可。
gawk -F" ;"’/tparker/{print}’ /etc/passwd
在此例中,你將字元分隔符設定成分號。注意: - F必須是大寫的,而且必須在第一個引號之前。
10.元字元
gawk語言在格式匹配時有其特別的規則。例如, cat能夠和記錄中所有位置有這三個字元的欄位匹配。但有時你需要一些更為特別的匹配。如果你想讓cat只和concatenate匹配,則需要在格式兩端加上空格:
/ cat / {print}
再例如,你希望既和cat又和CAT匹配,則能使用或(|):
/ cat | CAT / {print}
在gawk中,有幾個字元有特別意義。下面列出能用在gawk格式中的這些字元:
• ^ 表示欄位的開始。
例如:
$3 ~ /^b/
如果第三個欄位以字元b開始,則匹配。
• $ 表示欄位的結束。
例如:
$3 ~ /b$/
如果第三個欄位以字元b結束,則匹配。
• . 表示和所有單字元m匹配。
例如:
$3 ~ /i.m/
如果第三個欄位有字元i,則匹配。
• | 表示“或”。
例如:
/ c a t | C AT/
和cat 或C AT字元匹配。
• * 表示字元的零到多次重複。
例如:
/UNI*X/
和U N X、U N I X、U N I I X、U N I I I X等匹配。
• + 表示字元的一次到多次重複。
例如:
/UNI+X/
和U N I X、U N I I X等匹配。
• \{a,b\} 表示字元a次到b次之間的重複。
例如:
/ U N I \ { 1,3 \ } X
和U N I X、U N I I X和U N I I I X匹配。
• ? 表示字元零次和一次的重複。
例如:
/UNI?X/
和UNX 和U N I X匹配。
• [] 表示字元的範圍。
例如:
/I[BDG]M/
和I B M、I D M和I G M匹配
• [^] 表示不在[ ]中的字元。
例如:
/I[^DE]M/
和所有的以I開始、M結束的包括三個字元的字串匹配,除了IDM和IEM之外。
11.呼叫gawk程式
當需要非常多對模式和動作時,你能編寫一個gawk程式(也叫做gawk指令碼)。在gawk程式中,你能省略模式和動作兩邊的引號,因為在gawk程式中,模式和動作從哪開始和從哪結束時是非常顯然的。
你能使用如下命令呼叫g a w k程式:
gawk -f scrīpt filename
此命令使gawk對檔案filename執行名為scrīpt的gawk程式。
如果你不希望使用預設的欄位分隔符,你能在f選項後面跟著F選項指定新的欄位分隔符(當然你也能在gawk程式中指定),例如,使用分號作為欄位分隔符:
gawk -f scrīpt -F";" filename
如果希望gawk 程式處理多個檔案,則把各個檔名羅列其後:
gawk -f scrīpt filename1 filename2 filename3 ...
預設情況下, gawk的輸出將送往螢幕。但你能使用Linux的重定向命令使gawk的輸出送往一個檔案:
gawk -f scrīpt filename > save_file
12.BEGIN和END
有兩個特別的模式在gawk中非常有用。BEGIN模式用來指明gawk開始處理一個檔案之前執行一些動作。BEGIN經常用來初始化數值,設定引數等。END模式用來在檔案處理完成後執行一些指令,一般用作總結或註釋。
BEGIN 和END中所有要執行的指令都應該用花括號括起來。BEGIN 和END必須使用大寫。
請看下面的例子:
BEGIN { print "Starting the process the file" }
$1 == "UNIX" {print}
$2 > 10 {printf "This line has a value of %d",$ 2 }
END { print "Finished processing the file. Bye!"}
此程式中,先顯示一條資訊: Starting the process the file,然後將所有第一個欄位等於
UNIX的整條記錄顯示出來,然後再顯示第二個欄位大於10 的記錄,最後顯示資訊: Finished processing the file. Bye!
13.變數
在gawk中,能用等號( = )給一個變數賦值:
var1=10
在gawk中,你不必事先宣告變數型別。
請看下面的例子:
$1 == "Plastic" { count = count + 1 }
如果第一個欄位是Plastic,則count的值加1。在此之前,我們應當給count賦予過初值,一般是在BEGIN部分。
下面是比較完整的例子:
BEGIN { count = 0 }
$5 == "UNIX" { count = count + 1 }
END { printf "%d occurrences of UNIX were found",count }
變數能和欄位和數值一起使用,所以,下面的表示式均為合法:
count = count + $6
count = $5 - 8
count = $5 + var1
變數也能是格式的一部分,例如:
$2 > max_value {print "Max value exceeded by ",$2 - max_value}
$4 - var1 $2){
print "The first column is larger"
}
else {
print "The second column is larger"
} )
15.2 while 迴圈
while 迴圈的語法如下:
while (expression){
c o m m a n d s
}
例如:
# interest calculation computes compound interest
# inputs from a file are the amount,interest_rateand years
{var = 1
while (var 0){
print line[var]
v a r - -
}
}
此段程式讀取一個檔案的每一行,並用相反的順序顯示出來。我們使用NR作為陣列的下標來儲存檔案的每一條記錄,然後在從最後一條記錄開始,將檔案逐條地顯示出來。
17.使用者自定義函式
複雜的gawk 程式常常能使用自己定義的函式來簡化。呼叫使用者自定義函式和呼叫內部函式的方法相同。函式的定義能放在gawk 程式的所有地方。
使用者自定義函式的格式如下:
function name (parameter-list) {
b o d y - o f - f u n c t i o n
}
name 是所定義的函式的名稱。一個正確的函式名稱可包括一序列的字母、數字、下標線(underscores),不過不可用數字做開頭。parameter-
list 是函式的全部引數的列表,各個引數之間以逗點隔開。body-of-function 包含gawk 的表示式,他是函式定義裡最重要的部分,他決定函式實際要做的事情。
下面這個例子,會將每個記錄的第一個欄位的值的平方和第二個欄位的值的平方加起來。
{print "sum =",S q u a r e S u m ( $ 1,$ 2 ) }
function SquareSum(x,y) {
s u m = x * x + y * y
return sum
}
到此,我們已知道了gawk的基本用法。gawk語言十分易學好用,例如,你能用gawk編寫一段小程式來計算一個目錄中所有檔案的個數和容量。如果用其他的語言,如C語言,則會十分的麻煩,相反,gawk只需要幾行就能完成此工作。
18.幾個例項
最後,再舉幾個gawk的例子:
gawk ’{if (NF > max) max = NF}
END {print max}’
此程式會顯示所有輸入行之中欄位的最大個數。
gawk ’length($0) > 80’
此程式會顯示出超過80 個字元的每一行。此處只有模式被列出,動作是採用預設值顯示整個記錄。
gawk ’NF > 0’
顯示擁有至少一個欄位的所有行。這是個簡單的方法,將一個檔案裡的所有空白行刪除。
gawk ’BEGIN {for (i = 1; i
grep
grep (global search regular expression(RE) and print out the line,全方面搜尋正規表示式並把行列印出來)是一種強大的文字搜尋工具,他能使用正規表示式搜尋文字,並把匹配的行列印出來。Unix的grep家族包 括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有非常小不同。egrep是grep的擴充套件,支援更多的re元字元, fgrep就是fixed grep或fast grep,他們把所有的字母都看作單詞,也就是說,正規表示式中的元字元表示回其自身的字面意義,不再特別。linux使用GNU版本的grep。他功能 更強,能透過-G、-E、-F命令列選項來使用egrep和fgrep的功能。
grep的工作方式是這樣的:他在一個或多個檔案中搜尋字串模板。如果模板包括空格,則必須被引用,模板後的所有字串被看作檔名。搜尋的結果被送到螢幕,不影響原檔案內容。
grep可用於shell指令碼,因為grep透過返回一個狀態值來說明搜尋的狀態,如果模板搜尋成功,則返回0,如果搜尋不成功,則返回1,如果搜尋的檔案不存在,則返回2。我們利用這些返回值就可進行一些自動化的文字處理工作。
1. grep正規表示式元字符集(基本集)
^ 錨定行的開始 如:’^grep’匹配所有以grep開頭的行。
$ 錨定行的結束 如:’grep$’匹配所有以grep結尾的行。
. 匹配一個非換行符的字元 如:’gr.p’匹配gr後接一個任意字元,然後是p。
* 匹配零個或多個先前字元 如:’*grep’匹配所有一個或多個空格後緊跟grep的行。 .*一起用代表任意字元。
[] 匹配一個指定範圍內的字元,如’[Gg]rep’匹配Grep和grep。
[^] 匹配一個不在指定範圍內的字元,如:’[^A-FH-Z]rep’匹配不包含A-R和T-Z的一個字母開頭,緊跟rep的行。
\(..\) 標記匹配字元,如’\(love\)’,love被標記為1。
\錨定單詞的開始,如:’\匹配包含以grep開頭的單詞的行。
\> 錨定單詞的結束,如’grep\>’匹配包含以grep結尾的單詞的行。
x\{m\} 重複字元x,m次,如:’0\{5\}’匹配包含5個o的行。
x\{m,\} 重複字元x,至少m次,如:’o\{5,\}’匹配至少有5個o的行。
x\{m,n\} 重複字元x,至少m次,不多於n次,如:’o\{5,10\}’匹配5--10個o的行。
\w 匹配文字和數字字元,也就是[A-Za-z0-9],如:’G\w*p’匹配以G後跟零個或多個文字或數字字元,然後是p。
\W \w的反置形式,匹配一個或多個非單詞字元,如點號句號等。
\b 單詞鎖定符,如: ’\bgrepb\’只匹配grep。
2. 用於egrep和 grep -E的元字元擴充套件集
+ 匹配一個或多個先前的字元。如:’[a-z]+able’,匹配一個或多個小寫字母后跟able的串,如loveable,enable,disable等。
? 匹配零個或多個先前的字元。如:’gr?p’匹配gr後跟一個或沒有字元,然後是p的行。
a|b|c 匹配a或b或c。如:grep|sed匹配grep或sed
() 分組符號,如:love(able|rs)ov+匹配loveable或lovers,匹配一個或多個ov。
x{m},x{m,},x{m,n} 作用同x\{m\},x\{m,\},x\{m,n\}
4. POSIX字元類
為了在不同國家的字元編碼中保持一至,POSIX(The Portable
Operating System Interface)增加了特別的字元類,如[:alnum:]是A-Za-z0-9的另一個寫法。要把他們放到[]號內才能成為正規表示式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支援POSIX的字元類。
[:alnum:] 文字數字字元
[:alpha:]文字字元
[:digit:] 數字字元
[:graph:] 非空字元(非空格、控制字元)
[:lower:] 小寫字元
[:cntrl:] 控制字元
[:print:] 非空字元(包括空格)
[:punct:] 標點符號
[:space:] 所有空白字元(新行,空格,製表符)
[:upper:] 大寫字元
[:xdigit:] 十六進位制數字(0-9,a-f,A-F)
4. Grep命令選項
-? 同時顯示匹配行上下的?行,如:grep -2 pattern filename同時顯示匹配行的上下2行。
-b,--byte-offset 列印匹配行前面列印該行所在的塊號碼。
-c,--count 只列印匹配的行數,不顯示匹配的內容。
-f File,--file=File 從檔案中提取模板。空檔案中包含0個模板,所以什麼都不匹配。
-h,--no-filename 當搜尋多個檔案時,不顯示匹配檔名字首。
-i,--ignore-case 忽略大小寫差別。
-q,--quiet 取消顯示,只返回退出狀態。0則表示找到了匹配的行。
-l,--files-with-matches 列印匹配模板的檔案清單。
-L,--files-without-match 列印不匹配模板的檔案清單。
-n,--line-number 在匹配的行前面列印行號。
-s,--silent 不顯示關於不存在或無法讀取檔案的錯誤資訊。
-v,--revert-match 反檢索,只顯示不匹配的行。
-w,--word-regexp 如果被\和\>引用,就把表示式做為一個單詞搜尋。
-V,--version 顯示
[url=javascript:;]軟體[/url]
版本資訊。
5. 例項
要用好grep這個工具,其實就是要寫好正規表示式,所以這裡不對grep的所有功能進行例項講解,只列幾個例子,講解一個正規表示式的寫法。
$ ls -l | grep ’^a’
透過管道過濾ls -l輸出的內容,只顯示以a開頭的行。
$ grep ’test’ d*
顯示所有以d開頭的檔案中包含test的行。
$ grep ’test’ aa bb cc
顯示在aa,bb,cc檔案中匹配test的行。
$ grep ’[a-z]\{5\}’ aa
顯示所有包含每個字串至少有5個連續小寫字元的字串的行。
$ grep ’w\(es\)t.*\1’ aa
如果west被匹配,則es就被儲存到記憶體中,並標記為1,然後搜尋任意個字元(.*),這些字元後面緊跟著另外一個es(\1),找到就顯示該行。如果用egrep或grep -E,就不用"\"號進行轉義,直接寫成’w(es)t.*\1’就能了。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16396910/viewspace-1029544/,如需轉載,請註明出處,否則將追究法律責任。

相關文章