sed命令用法詳解

sed命令用法

sed是一種流編輯器,它是文本處理中非常有用的工具,能夠完美的配合正則表達式使用,功能不同凡響。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲『模式空間』(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。文件內容並沒有改變,除非你使用重定向存儲輸出。sed主要用來自動編輯一個或多個文件,簡化對文件的反覆操作,編寫轉換程序等。

sed的選項、命令、替換標記

命令格式

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

選項

參數 完整參數 說明
-e script --expression=script 以選項中的指定的script來處理輸入的文本文件
-f script --files=script 以選項中的指定的script文件來處理輸入的文本文件
-h --help 顯示幫助
-n --quiet --silent 僅顯示script處理後的結果
-V --version 顯示版本信息

參數

文件:指定待處理的文本文件列表

sed命令

命令 說明
d 刪除,刪除選擇的行
D 刪除模板塊的第一行
s 替換指定字符
h 拷貝模板塊的內容到內存中的緩衝區
H 追加模板塊的內容到內存中的緩衝區
g 獲得內存緩衝區的內容,並替代當前模板塊中文本
G 獲得內存緩衝區的內容,並追加到當前模板塊文本的後面
l 列表不能打印字符的清單
n 讀取下一個輸入行,用下一個命令處理新的行而不是第一個命令
N 追加下一個輸入行到模板塊後面並在二者間嵌入一個新行,改變當前行號碼
p 打印模板塊的行
P 打印模板塊的第一行
q 退出sed
b label 分支到腳本中帶有標記的地方,如果分支不存在則分支到腳本的末尾
r file 從file中讀行
t label if分支,從最後一行開始,條件一旦滿足或者T,t命令,將導致分支到帶有標號的命令處,或者到腳本的末尾
T label 錯誤分支,從最後一行開始,一旦發生錯誤或者T,t命令,將導致分支到帶有標號的命令處,或者到腳本的末尾
w file 寫並追加模板塊到file末尾
W file 寫並追加模板塊的第一行到file末尾
! 表示後面的命令對所有沒有被選定的行發生作用
= 打印當前行號
# 把註釋擴展到第一個換行符以前

sed替換標記

命令 說明
g 表示行內全面替換
p 表示打印行
w 表示把行寫入一個文件
x 表示互換模板塊中的文本和緩衝區中的文本
y 表示把一個字符翻譯爲另外的字符(但是不用於正則表達式)
\1 子串匹配標記
& 已匹配字符串標記

sed元字符集

命令 說明
^ 匹配行開始,如:/^sed/匹配所有以sed開頭的行。
$ 匹配行結束,如:/sed$/匹配所有以sed結尾的行。
. 匹配一個非換行符的任意字符,如:/s.d/匹配s後接一個任意字符,最後是d。
* 匹配0個或多個字符,如:/*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開頭的單詞的行。
 > 匹配單詞的結束,如/love>/匹配包含以love結尾的單詞的行。
x{m} 重複字符x,m次,如:/0{5}/匹配包含5個0的行。
x{m,} 重複字符x,至少m次,如:/0{5,}/匹配至少有5個0的行。
x{m,n} 重複字符x,至少m次,不多於n次,如:/0{5,10}/匹配5~10個0的行。

sed用法實例

我們先準備一個測試文件

MacBook-Pro:tmp maxincai$ cat test.txt
my cat's name is betty
This is your dog
my dog's name is frank
This is your fish
my fish's name is george
This is your goat
my goat's name is adam

替換操作:s命令

替換文本中的字符串:

MacBook-Pro:tmp maxincai$ sed 's/This/aaa/' test.txt
my cat's name is betty
aaa is your dog
my dog's name is frank
aaa is your fish
my fish's name is george
aaa is your goat
my goat's name is adam

-n選項和p命令一起使用表示只打印那些發生替換的行:

MacBook-Pro:tmp maxincai$ sed -n 's/This/aaa/p' test.txt
aaa is your dog
aaa is your fish
aaa is your goat

測試過程中發現mac os x和linux還是有點不一樣,換回centos 6.5進行測試

直接編輯文件選項-i,會匹配test.txt文件中每一行的第一個This替換爲this:

[root@vagrant-centos65 workspace]# sed -i 's/This/this/' test.txt
[root@vagrant-centos65 workspace]# cat test.txt
my cat's name is betty
this is your dog
my dog's name is frank
this is your fish
my fish's name is george
this is your goat
my goat's name is adam

全面替換標記g

使用後綴/g標記會替換每一行中的所有匹配:

[root@vagrant-centos65 workspace]# sed 's/this/This/g' test.txt
my cat's name is betty
This is your This dog
my dog's name is This frank
This is your fish
my fish's name is This george
This is your goat
my goat's name is This adam

當需要從第N處匹配開始替換時,可以使用/Ng:

[root@vagrant-centos65 workspace]# echo sksksksksksk | sed 's/sk/SK/2g'
skSKSKSKSKSK
[root@vagrant-centos65 workspace]# echo sksksksksksk | sed 's/sk/SK/3g'
skskSKSKSKSK
[root@vagrant-centos65 workspace]# echo sksksksksksk | sed 's/sk/SK/4g'
skskskSKSKSK

定界符

以上命令中字符 / 在sed中作爲定界符使用,也可以使用任意的定界符:

[root@vagrant-centos65 workspace]# echo sksksksksksk | sed 's:sk:SK:4g'
skskskSKSKSK
[root@vagrant-centos65 workspace]# echo sksksksksksk | sed 's|sk|SK|4g'
skskskSKSKSK

定界符出現在樣式內部時,需要進行轉義:

[root@vagrant-centos65 workspace]# echo '/usr/local/bin' | sed 's/\/usr\/local\/bin/\/USR\/LOCAL\/BIN/g'
/USR/LOCAL/BIN

刪除操作:d命令

刪除空白行:

[root@vagrant-centos65 workspace]# cat test.txt
my cat's name is betty

this is your this dog

my dog's name is this frank

this is your fish

my fish's name is this george

this is your goat

my goat's name is this adam

[root@vagrant-centos65 workspace]# sed '/^$/d' test.txt
my cat's name is betty
this is your this dog
my dog's name is this frank
this is your fish
my fish's name is this george
this is your goat
my goat's name is this adam

刪除文件的第2行:

[root@vagrant-centos65 workspace]# sed '2d' test.txt
my cat's name is betty
my dog's name is this frank
this is your fish
my fish's name is this george
this is your goat
my goat's name is this adam

刪除文件的第2行到末尾所有行:

[root@vagrant-centos65 workspace]# sed '2,$d' test.txt
my cat's name is betty

刪除文件最後一行:

[root@vagrant-centos65 workspace]# sed '$d' test.txt
my cat's name is betty
this is your this dog
my dog's name is this frank
this is your fish
my fish's name is this george
this is your goat

刪除文件中所有以my開頭的行:

[root@vagrant-centos65 workspace]# sed '/^my/'d test.txt
this is your this dog
this is your fish
this is your goat

已匹配字符串標記&

正則表達式\w\+匹配每一個單詞,使用[&]替換它,&對應之前所匹配到的單詞:

[root@vagrant-centos65 workspace]# echo this is a test line | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]

子串匹配標記\1

匹配給定樣式的其中一部份:

[root@vagrant-centos65 workspace]# echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
this is 7 in a number

命令中digit 7,被替換成7.樣式匹配到的子串是7,\(..\)用於匹配子串,對於匹配到的第一個子串標記爲\1,依此類推匹配到的第二個結果就是\2,例如:

[root@vagrant-centos65 workspace]# echo aaa BBB | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
BBB aaa

組合多個表達式

sed '表達式' | sed '表達式'

等價於

sed '表達式; 表達式'

引用

sed表達式可以使用單引號來引用,但是如果表達式內部包含變量字符串,就需要使用雙引號。

[root@vagrant-centos65 workspace]# test=hello
[root@vagrant-centos65 workspace]# echo hello WORLD | sed "s/$test/HELLO/"
HELLO WORLD

選定行的範圍:,(逗號)

打印從第5行開始到第一個包含以this開始的行之間的所有行:

[root@vagrant-centos65 workspace]# sed -n '5,/^this/p' test.txt
my fish's name is this george
this is your goat

多點編輯:e命令

-e選項允許在同一行裏執行多條命令:

[root@vagrant-centos65 workspace]# sed -e '1,5d' -e 's/my/MY/' test.txt
this is your goat
MY goat's name is this adam

上面sed表達式的第一條命令刪除1至5行,第二條命令用check替換test。命令的執行順序對結果有影響。如果兩個命令都是替換命令,那麼第一個命令將影響第二個命令的結果。

和 -e 等價的命令是 --expression

從文件讀入:r命令

file裏的內容被讀進來,顯示在與test匹配的行後面,如果匹配多行,則file的內容將顯示在所有匹配行的下面:

[root@vagrant-centos65 workspace]# cat test1.txt
aaaaaaaa
[root@vagrant-centos65 workspace]# sed '/my/r test1.txt' test.txt
my cat's name is betty
aaaaaaaa
this is your this dog
my dog's name is this frank
aaaaaaaa
this is your fish
my fish's name is this george
aaaaaaaa
this is your goat
my goat's name is this adam
aaaaaaaa

寫入文件:w命令

在test.txt中所有包含my的行都被寫入test2.txt裏:

[root@vagrant-centos65 workspace]# sed -n '/my/w test2.txt' test.txt
[root@vagrant-centos65 workspace]# cat test2.txt
my cat's name is betty
my dog's name is this frank
my fish's name is this george
my goat's name is this adam

追加(行下):a\命令

將this is a test line 追加到以my開頭的行後面:

[root@vagrant-centos65 workspace]# sed '/^my/a\this is a test line' test.txt
my cat's name is betty
this is a test line
this is your this dog
my dog's name is this frank
this is a test line
this is your fish
my fish's name is this george
this is a test line
this is your goat
my goat's name is this adam
this is a test line

在text.txt文件第2行之後插入this is a test line:

[root@vagrant-centos65 workspace]# sed '2a\this is a test line' test.txt
my cat's name is betty
this is your this dog
this is a test line
my dog's name is this frank
this is your fish
my fish's name is this george
this is your goat
my goat's name is this adam

插入(行上):i\命令

將this is a test line 插入到以my開頭的行前面:

[root@vagrant-centos65 workspace]# sed '/^my/i\this is a test line' test.txt
this is a test line
my cat's name is betty
this is your this dog
this is a test line
my dog's name is this frank
this is your fish
this is a test line
my fish's name is this george
this is your goat
this is a test line
my goat's name is this adam

下一個:n命令

如果my被匹配,則移動到匹配行的下一行,替換這一行的this爲This,並打印該行:

[root@vagrant-centos65 workspace]# sed '/my/{n; s/this/This/; }' test.txt
my cat's name is betty
This is your this dog
my dog's name is this frank
This is your fish
my fish's name is this george
This is your goat
my goat's name is this adam

變形:y命令

把1-10行內所有的abcde轉變爲大寫,注意,正則表達式元字符不能使用這個命令:

[root@vagrant-centos65 workspace]# sed '1,10y/abcde/ABCDE/' test.txt
my CAt's nAmE is BEtty
this is your this Dog
my Dog's nAmE is this frAnk
this is your fish
my fish's nAmE is this gEorgE
this is your goAt
my goAt's nAmE is this ADAm

退出:q命令

打印完第3行,退出sed

[root@vagrant-centos65 workspace]# sed '3q' test.txt
my cat's name is betty
this is your this dog
my dog's name is this frank

打印奇數行或偶數行

方法1:

奇數行

[root@vagrant-centos65 workspace]# sed -n 'p;n' test.txt
my cat's name is betty
my dog's name is this frank
my fish's name is this george
my goat's name is this adam

偶數行

[root@vagrant-centos65 workspace]# sed -n 'n;p' test.txt
this is your this dog
this is your fish
this is your goat

方法2:

sed -n '1~2p' test.txt
sed -n '2~2p' test.txt

更多的需要在以後的工作中慢慢摸索,這裏只是一個簡單的記錄,以後如果有更多經驗了再完善一篇sed實戰吧。

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