sed 即 stream editor,一個簡單而強大的文本解析轉換工具,1973-1974年期間由貝爾實驗室的 Lee E. McMahon 開發,能夠完美的配合正則表達式使用。
處理文本時,當前處理的行會先存儲在臨時緩沖區中,稱為模式空間(pattern space),操作完成后再把緩沖區的內容送往屏幕。接著處理下一行,直到文件末尾。文件內容并沒有改變,除非使用重定向存儲輸出。
sed 主要用來自動編輯一個或多個文件,簡化對文件的反復操作,編寫轉換程序等。
1. 使用 s 命令替換
基本使用
sed 默認情況下通過 STDIN 輸入流讀取數據,可以利用管道符(|)進行重定向。如下:
$ echo "This is a test" | sed 's/test/big test/'
This is a big test
s 替換命令的格式為:s/pattern/replacement/flags
,如下:
$ cat test.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$
$ sed 's/dog/cat/' test.txt
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
使用 s 命令進行替換時,默認只替換每行中的第一個匹配。全局替換需增加 g 選項。
$ sed 's/o/O/g' test.txt
The quick brOwn fOx jumps Over the lazy dOg.
The quick brOwn fOx jumps Over the lazy dOg.
The quick brOwn fOx jumps Over the lazy dOg.
The quick brOwn fOx jumps Over the lazy dOg.
sed 默認只將處理后的內容輸出,而不對原文件的內容做任何改動。如需寫入文件,可使用重定向:$ sed 's/dog/cat/' test.txt > test2.txt
或通過 -i 選項直接修改文件內容:$ sed -i 's/dog/cat/' test.txt
address
如果需要將命令應用到特定的一行或多行內容,可以使用 line addressing。格式為 [address[,address]][!]command
。
address 可以是數字或模式,也可以通過逗號分隔兩個 address 表示一個區間范圍。
如只將第2行中的 dog 替換為 cat:
$ sed '2s/dog/cat/' test.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
或者$ sed '1,3s/dog/cat/' test.txt
,替換1-3行的內容。
$ sed '2,$s/dog/cat/' test.txt
,替換第2行到最后一行的內容。
! 表示完成匹配后是否在該行執行替換命令。加上 ! 表示不執行。如下:
$ cat lines.txt
This is line one
This is line two
This is line three
This is line four
$
$ sed '/one/,2s/line/LINE/' lines.txt
This is LINE one
This is LINE two
This is line three
This is line four
$
$ sed '/one/,2!s/line/LINE/' lines.txt
This is line one
This is line two
This is LINE three
This is LINE four
替換選項
sed 的替換命令除了可以附加 g 選項(全局替換)外,還有更多選項適用于不同的情形。
- 數字。表示只替換每行中的第 n 個匹配項,如:
$ sed 's/o/O/2' test.txt
The quick brown fOx jumps over the lazy dog.
The quick brown fOx jumps over the lazy dog.
The quick brown fOx jumps over the lazy dog.
The quick brown fOx jumps over the lazy dog.
或$ sed 's/o/O/2g' test.txt
替換每行中從第二個開始的所有匹配項(即替換每行中從第二個 o 開始直到該行行尾的所有 o 字符)
- p,表示打印處理前的原始內容,結合上 -n 選項(不打印輸出)則可以只輸出處理過的內容。
$ sed 's/three/3/p' lines.txt
This is line one
This is line two
This is line 3
This is line 3
This is line four
$
$ sed -n 's/three/3/p' lines.txt
This is line 3
- w,將處理過的內容寫入文件
$ sed 's/three/3/w line3.txt' lines.txt
$
$ cat line3.txt
This is line 3
sed 命令選項
- 刪除:d
$ sed '2,$d' lines.txt
刪除 lines.txt 中第2行到最后一行的內容。
$ sed '/two/d' lines.txt
刪除 lines.txt 中包含 two 的行。 - 追加(行下):a
$ sed '/two/a\
> This is a line behind line 2' lines.txt
This is line one
This is line two
This is a line behind line 2
This is line three
This is line four
- 插入(行上):i
$ sed '2i\
> This is a line above line 2' lines.txt
在第2行以上插入內容。
- 修改:c
$ sed '/two/c\
> Line 2' lines.txt
將包含 two 的行修改為 Line 2(整行內容替換為 Line 2)。
- 字符轉換:y
格式為:[address]y/inchars/outchars/
輸入文件中所有包含在 inchars 中的字符都將替換為 outchars 中對應的字符。
$ cat line_number.txt
This is line 1.
This is line 2.
This is line 3.
This is another line 1.
$
$ sed 'y/123/456/' line_number.txt
This is line 4.
This is line 5.
This is line 6.
This is another line 4.
其他用法
- 打印輸出
sed 的 p 命令可以達到類似 grep 的效果,結合上 address 功能還可以完成更復雜的篩選打印操作。
$ sed -n 'p' lines.txt
This is line one
This is line two
This is line three
This is line four
$
$ sed -n '2,3p' lines.txt
This is line two
This is line three
$
$sed -n '/two/,/three/p' lines.txt
This is line two
This is line three
- 多個匹配
可以通過 -e 選項實現多個匹配的替換
$ sed -e 's/fox/kangaroo/;s/dog/cat/' test.txt
The quick brown kangaroo jumps over the lazy cat.
The quick brown kangaroo jumps over the lazy cat.
The quick brown kangaroo jumps over the lazy cat.
The quick brown kangaroo jumps over the lazy cat.
也可以這樣:
$ sed -e '
> s/brown/red/
> s/fox/kangaroo/
> s/dog/cat/' test.txt
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
- 從腳本文件中讀取命令
$ cat script.sed
s/brown/red/
s/fox/kangaroo/
s/dog/cat
$
$ sed -f script.sed test.txt
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
The quick red kangaroo jumps over the lazy cat.
- 可以使用 & 變量表示前面的匹配項,如:
$ sed 's/fox/&es/' test.txt
The quick brown foxes jumps over the lazy dog.
The quick brown foxes jumps over the lazy dog.
The quick brown foxes jumps over the lazy dog.
The quick brown foxes jumps over the lazy dog.
參考書籍和文章:
Linux Command Line and Shell Scripting Bible, 3rd Edition
SED 簡明教程 by 陳皓
Linux 命令大全 / SED 命令