每週一薦:流編輯器sed

做網絡遊戲服務器端,最煩人的就是查後臺日誌。外面的玩家報BUG或者其他異常的時候,客服搞不定的時候,就需要服務器的程序去查日誌。分析日誌需要一些比較好的文本分析工具,grep和sed都是不錯的文本分析工具,還有awk,再過複雜的日誌分析估計就要寫腳本了,推薦使用Python。

(其實我一直在納悶,數據分析這些事情,怎麼老是需要服務器程序去查,有專門的數據中心、運維和客服部門,人家纔是專業的,工具比咱用的更“專業”吧。最後想了想,公司流程不完善,遊戲後臺日誌分析自己這邊還是做起來,不然搞的太被動了也不好。)

下面是sed的一個快速參考,更加詳細的介紹,還有用法實例,可以參考《sed and awk》那本書。或者本文後面的那幾個鏈接,都有很好的介紹。

命令行語法

有兩種調用sed的方式:

 sed [-n] [-e] 'command' file(s)
 sed [-n] -f scriptfile file(s)

第一種方式允許在命令行指定一個編輯命令,用單引號括起來。第二種形式允許指定一個scriptfile,即包含sed命令的文件。兩種形式可以一起使用,並且他們可以被多次使用。編輯的結構是將命令和腳本文件串聯起來。

下面是可識別的選項:

-n
	僅打印用p命令或s命令標記指定的行
-e cmd
	下一個參數是編輯命令。當指定多個腳本時很有用。
-f file
	下一個參數是一個包含編輯命令的文件。

如果腳本的第一行是”#n”,sed將按-n指定的方式工作。

頻繁使用sed腳本通常是通過shell腳本來調用的。

sed命令語法

sed命令的一般形式爲:

   [address[,address]][!]command[arguments]

sed將每個輸入行拷貝到一個模式空間。sed指令由地址和編輯命令組成。如果命令的地址和模式空間中的行匹配,那麼這個命令將被應用於匹配行。如果一個命令沒有地址,那麼它被應用於每個輸入行。如果一個命令改變了模式空間的內容,後續的命令地址將被應用與模式空間中的當前行,而不是原始的輸入行。

模式尋址

地址可以是一個行號或是由斜槓包含着的一個模式(/pattern/)。模式是用正則表達式表示的。另外,\n可以用來與模式空間(N命令的結果)的任意換行符匹配,但模式空間底部的換行符除外。
如果沒有指定模式,相應的命令將被應用於所有的行。如果只指定一個地址,那麼相應的命令將被應用於和這個地址匹配的行。如果指定了兩個用逗號分隔的地址,這個命令將被應用於位於第一個和第二個地址範圍之間的所有行。一些命令只接收一個地址,包括a,i,r,q和=。

在地址後面的”!”操作符使sed將相應的命令作用於所有與該地址不匹配的行。

大括號({})被sed用於地址的嵌套或對同一個地址應用多個命令。

	[/pattern/[,/pattern/]] {
	command1
	command2
	}

左大括號必須在一行的末尾,而右括號必須單獨在一行。確保大括號後面沒有空格。

sed中的正則表達式元字符

.
匹配除換行符以爲的任意單個字符
*
匹配任意個(包括0個)在它前面的字符(包括由正則表達式指定的字符)
[...]
匹配廣括號中的字符中的任意一個字符。其它所有的元字符被指定爲其中成員時都會失去它們原來的含義。如果方括號第一個字符爲脫字符(^)則匹配除了換行符和列出的那些字符以爲的所有字符。連字符(-)用來表示字符的範圍。如果其中第一個字符爲右方括號(]),則表示它是這個類的成員。
\{n,m\}
它前面的某個範圍內單個字符出現的次數(保護正則表達式指定的字符)。\{n\}將匹配n次出現,\{n,\}匹配大於等於n次出現的。
^
定位位於行起始位置後面的正則表達式。只有當^符號出現在正則表達式的起始位置時纔是特殊的。
$
定位位於行末尾的正則表達式,只有當$符號出現在正則表達式的末尾時纔是特殊的。
\
轉義隨後的特殊字符
\( \)
將包含在”"和”"之間的模式保存到一個特殊的保持空間。用這種方法在一行中可以最多保存9個模式。用轉義序列”\1″ 到 “\9″ 可以重新使用它們。
\n
匹配前面”"和”"保存的第n個模式,這裏n是一個從1到9的數字,前面保存的模式從行的左邊開始編號。
&
當在替換字符串中使用時打印整個被匹配的文本

sed命令參考

命令 說明
: :lable
在腳本中標記一行,用於實現由b或t的控制轉移。label最多可以包含7個字符。(GNU sed允許標籤的長度任意)
= [address]=
將所尋址的行編號寫到標準輸出。
a [address]a\
     text
在與address匹配的每行後面追加text。如果text多於一行,必須用反斜槓將這些行前面的換行符“隱藏”起來。text將被沒有用這種方法隱藏的第一個換行符結束。text在模式空間中不是可用的並且後續命令不能應用於它。當編輯命令的列表用完時這個命令的結果將被輸送到標準輸出,而不管在模式空間中的當前行發生了什麼。
c [address1[,address2]]c \
    text
用text代替(改變)由地址選定的行。當指定的是一個行範圍時,將所有的這些行爲作爲一個組由text的一個副本來代替。每個text行後面的換行符必須用反斜槓將其轉義,但最後一行除外。實際上,模式空間的內容被刪除,因此後續的命令不能應用於它(或應用於text)
d [address1[,address2]]d
從模式空間中刪除行。因此行沒有被傳遞到標準輸出。一個新的輸入行被讀取,並用腳本的第一個命令來編輯。
D [address1[,address2]]D
刪除由命令N穿件的多行模式空間中的第一部分(直接嵌入的換行符),並且用腳本的第一條命令恢復編輯。如果這個命令使模式空間爲空,那麼將讀取一個新的輸入行,和執行了d命令。
g [address1[,address2]]g
將保持空間中的內容複製到模式空間。如果保持空間爲空,則將換行符添加到模式空間。
G [address1[,address2]]G
將保持空間中的內容追加到模式空間。如果保持空間爲空,則將換行符添加到模式空間。
h [address1[,address2]]h
將模式空間的內容複製到保持空間,即一個特殊的臨時緩衝區。保持空間的當前內容被清楚。
H [address1[,address2]]H
將換行符和模式空間的內容追加到保持空間中,即使保持空間爲空,這個命令也追加換行符。
i [address]i\
    text
將text插入到每個和address匹配的行的前面。
l [address1[,address2]]l
列出模式空間的內容,將不可打印的字符表示爲ASCII碼。長的行被折行。
n [address1[,address2]]n
讀取下一個輸入行到模式空間。當前行被送到標準輸出。新行成爲當前行並遞增計數器。將控制轉到n後面的命令,而不是恢復到腳本的頂部。
N [address1[,address2]]N
將下一個輸入行追加到模式空的內容之後;新添加的行與模式空間的當前內容用換行符分隔(這個命令用於實現兩行的模式匹配。利用\n來匹配嵌入的換行符,則可以實現多行模式匹配)
p [address1[,address2]]p
打印所尋址的行。注意這將導致輸出的重複,除非默認的輸出用”#n”或”-n”命令行選項限制。常用於改變流控制(d,n,b)的命令之前並可能阻止當前行被輸出。
P [address1[,address2]]P
打印由N命令創建的多行模式空間的地一部分(直接嵌入的換行符)。如果沒有將N應用於某一行則和p相同。
q [address]q
當遇到address時退出。尋址的行首先被寫到輸出(如果沒有限制默認輸出),包括用前面的a或r命令爲它追加的文本。
r [address]r file
讀取file的內容並追加到模式空間內容的後面。必須在r和文件名file之間保留一個空格。
s [address1[,address2]]s/pattern/replacement/[flags]
用replacement代替每個尋址行的pattern。如果使用了模式地址,那麼模式//表示最後指定的模式地址。可指定下面的標誌。

  • n 替代每個尋址的行的地n個/pattern/。n是1到512之間的任意數值,並默認致爲1。
  • g 替代每個尋址的行的所有/pattern/,而不只是第一個。
  • p 如果替換成功則打印這一行。如果成功進行了多次替換,將打印這個行的多個副本。
  • w file 如果發生一次替換則將這行寫入file。最多可以打開10個不同的file。
t [address1[,address2]]t [label]
測試在尋址的行範圍內是否成功執行了替換,如果是,則轉移到有lable標誌的行。如果沒有給出lable,控制轉移到腳本的底部。
w [address1[,address2]]w file
將模式空間的內容追加到file。這個動作是在遇到命令時發生而不是在輸出模式空間內容時發生。必須在w和這個文件名之間保留一個空格。在腳本中可以打開的最大文件數是10。如果文件不存在,這個命令將創建一個文件。如果文件存在,則每次執行腳步時將修改其內容,多重寫入命令直接將輸出寫入到同一個文件並追加到這個文件的末端。
x [address1[,address2]]x
交換模式空間和保持空間的內容。
y [address1[,address2]]y/abc/xyz/
安位置將字符串abc中的字符轉換成字符串xyz中的相應該字符。

 

更多參考資料

  1. sed快速參考
  2. sed基本用法介紹
  3. sed單行腳本實例

2012/04/20 23:45 於上海

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章