sed
用於篩選和轉換文本的流編輯器
描述:
sed是一個流編輯器,流編輯器對一個輸入流執行基本的文本轉換(輸入流來自文件或者管道行)。雖然在某些方面相似於不少可運行腳本的編輯器,可是sed的工做方式是每次只處理一個輸入(能夠理解爲一個模式空間),所以更高效。可是sed在管道中過濾文本的做用使它明顯區別於其餘類型編輯器。
命令格式:
sed [OPTION] {script} file
選項
-n, --quiet, --silent
抑制模式空間的自動打印
例如
echo -e "abc\ndef" | sed 'p'
#輸出 abc
# abc
# def
# def
echo -e "abc\ndef" | sed -n 'p'
#輸出 abc
# def
-e script, --expression=script
添加腳本到將要被執行的命令
例如
echo -e "abc\ndef" | sed -n -e 's/abc/ghi/' -e 'p'
# 輸出 ghi
# def
-f script-file, --file=script-file
將腳本文件的內容添加到要執行的命令
--follow-symlinks
處理符號連接
-i[SUFFIX], --in-place[=SUFFIX]
編輯文件(若是提供了SUFFIX ,則對原文件先進行備份)
例如
sed -i_bak '1d' aaa
# 將先生成aaa的備份文件aaa_bak
-l N, --line-length=N
爲’l‘命令指定但願的行摺疊長度
--posix
禁用全部的GNU擴展。
-r, --regexp-extended
在腳本中使用擴展的正則表達式。
-s, --separate
將文件視爲單個獨立的文件,而不是將它們視爲整個連續的字符流。
-u, --unbuffered
從輸入中加載儘量少許的數據而且更頻繁的刷新
--help
顯示幫助而且退出
--version
輸出版本信息並退出
命令
0地址命令
: label
爲b和t命令定義標籤。
#comment
註釋一行
}
塊結束符號
0地址或者1地址命令
=
打印當前的行號
a \
text
追加新行
追加文本,(模式空間內的)每一行後都將追加(新行)反斜槓後的文本。
例如
echo "abc" | sed 'a\def'
# 輸出 abc
# def
i \
text
插入新行
插入文本, (模式空間內的)每一行前都將插入(新行)反斜槓後的文本。
例如
echo "abc" | sed 'i\def'
# 輸出 def
# abc
q [exit-code]
當即退出sed腳本不處理任何更多的輸入, 除非自動打印是未禁用的狀況下當前的模式空間將被打印。退出碼參數是一個GNU擴展。
Q [exit-code]
當即退出sed腳本不處理任何更多的輸入。退出碼參數是一個GNU擴展。
r filename
追加從filename讀取的文本
R filename
追加從filename讀取的一行。每次調用命令從文件中讀取一行。這是一個GNU擴展。
接受地址範圍的命令
{
塊命令的開始,
b label
跳轉到標籤,若是label省略,跳轉到命令結尾。
c \
text
行替換
用text替換選中的行,每一行都將被反斜槓後的文本替換。
例如
echo -e "abc\ndef" | sed 'c\ghi'
# 輸出 ghi
# ghi
d
刪除模式空間。啓動下一個循環。
D
若是模式空間內沒有換行,開啓一個新的循環如同d命令被髮布。不然,刪除模式空間的文本直到換行,而且在新產生的模式空間中重啓循環,不從輸入讀入新行。
這個怎麼理解呢?當模式空間有多行時,D命令每次只刪除一行,而後從下一行開始新的循環,這裏的下一行是模式空間中的第二行,因此不從輸入讀入新行。
而d命令就會把模式空間所有刪除。而後從下一行開始循環,這裏的下一行就是從輸入讀取的新行了。
例如
echo -e "abc\ndef\nghi\njkl" | sed -n 'N;/abc\ndef/d;p'
# 輸出 ghi
# jkl
# sed共執行了2次循環,第一次循環以下
# N追加了一行,模式空間內容爲"abc\ndef";刪除模式空間;開始下一個循環,讀入輸入的第一行,模式空間內容爲"ghi";
# 第二次循環以下
# N追加了一行,模式空間內容爲"ghi\njkl";刪除操做未執行;打印模式空間。
echo -e "abc\ndef\nghi\njkl" | sed -n 'N;/abc\ndef/D;p;p'
# 輸出 def
# ghi
# def
# ghi
# sed共執行了2次循環,第一次循環以下
# N追加了一行,模式空間內容爲"abc\ndef";刪除模式空間的第一行,模式空間內容爲"def";開始下一個循環;
# 第二次循環以下
# N追加了一行,模式空間內容爲"def\nghi";刪除操做未執行;打印模式空間,打印模式空間。
h H
複製/追加 模式空間到保持空間。
g G
複製/追加 保持空間到模式空間。
例如
echo -e "abc\ndef" | sed -n 'h;n;g;p'
# 輸出 abc
echo -e "abc\ndef" | sed -n 'h;n;G;p'
# 輸出 def
# abc
echo -e "abc\ndef" | sed -n 'h;n;H;G;p'
# 輸出 def
# abc
# def
l
用視覺明確的格式列出當前行。
l width
用視覺明確的格式列出當前行,在第width個字符處阻斷(換行)。這是一個GNU擴展。
例如
echo -e "abc\ndef" | sed -n 'N;l'
# 輸出 abc\ndef$
echo -e "abc\ndef" | sed -n 'N;l 4'
# 輸出 abc\
# \nd\
# ef$
n N
讀取/追加 輸入的下一行到模式空間。
例如,下面的例子體現了大小寫n命令的區別
echo -e "abc\ndef" | sed -n 'n;p'
# 輸出 def
echo -e "abc\ndef" | sed -n 'N;p'
# 輸出 abc
# def
p
打印當前的模式空間。
P
打印(的內容只)到當前模式空間的第一個換行符。只打印一行的意思。
例如,下面的例子體現了大小寫p命令的區別
echo -e "abc\ndef" | sed -n 'N;/abc\ndef/p'
# 輸出 abc
# def
echo -e "abc\ndef" | sed -n 'N;/abc\ndef/P'
# 輸出 abc
s/regexp/replacement/
用replacement替換匹配的內容
嘗試對模式空間匹配正則表達式。若是成功,用replacement替換掉匹配的部分。replacement可能包含特殊的字符&引用已匹配的那部分。特殊的轉義\1到\9引用正則表達式中對應的子表達式。
例如
echo "abc" | sed 's/abc/def/'
# 輸出 def
echo "abc" | sed 's/abc/&def/'
# 輸出 abcdef
關於s命令的GNU擴展會在後文中描述,包括替換模式和其餘選項
t label
切換到分支label。
自從上一個輸入行被讀取而且(執行了)t或者T命令,若是s///已經完成一個成功的替換,切換到分支label;若是省略了標籤,則切換到腳本的結尾。
T label
自從上一個輸入行被讀取而且(執行了)t或者T命令,若是s///連一個成功的替換都沒有完成,切換到分支label;若是省略了標籤,則切換到腳本的結尾。這是一個GNU擴展。
w filename
寫當前的模式空間到文件filename。
W filename
寫當前模式空間的第一行到文件filename。這是一個GNU擴展。
x
交換模式空間和保持空間的內容。
y/source/dest/
將模式空間內source裏的字符轉換成dest裏對應的字符。
例如
echo "axxbxxcxx" | sed 'y/abc/123/'
# 輸出 1xx2xx3xx
sed命令能夠不給出地址,在這種狀況下將對全部的輸入行執行命令;
給出一個地址,這種狀況下只對匹配的輸入行執行命令;
或者給出2個地址,這種狀況下將對匹配的範圍內(第一個地址開始持續到第二個地址)的全部行執行命令。
關於地址範圍的三個注意事項:
1 語法是 addr1,addr2 (地址用逗號分割);
2 已經匹配的addr1的行老是被接受的,即便地址2選擇了一個較早的行(行號小於地址1);
3 若是addr2是一個正則表達式,它不會針對已經匹配的地址1的行進行測試。
如何理解第二條?就是說若是addr1匹配第5行,在第5行以後沒有匹配addr2的行,則將匹配第5行到輸入的結尾。
那麼 6,4 這種格式的地址呢? 6,4 = 6
地址以後命令以前,一個 !(感嘆號) 可能被插入,指明命令將被執行在不匹配的行上。
例如
echo -e "abc\ndef" | sed -n '1!p'
# 輸出 def
echo -e "abc\ndef" | sed -n '$!p'
# 輸出 abc
支持以下的地址類型:
number 匹配指定的行(跨文件累計增長,除非命令行指定-s選項)。
first~step 匹配first開始的每個階梯。
好比 sed -n 1~2p 將打印輸入流中的全部奇數行,地址 2~5 將匹配從第二行開始的每個第五行,
第一個數能夠是0,這種狀況下,sed操做每個階梯的倍數行。
$ 匹配最後一行
/regexp/ 匹配正則表達式regexp匹配的行。
\cregexpc 匹配正則表達式regexp匹配的行,c能夠是任意的字符。
好比有一行內容爲abcdefg,則\abcdefga將匹配該行。
GNU sed 也支持一些特殊的2個地址的格式:
0,addr2 開始於第一個地址匹配的狀態,直到匹配addr2的行被找到.這相似於 1,addr2,除了addr2匹配輸入的第一行,
0,addr2 格式認爲第一行是範圍的末尾,而 1,addr2 格式認爲第一行是範圍的開始。
這種格式只工做在addr2是正則表達式的狀況。
若是第一行匹配addr2,0,addr2 匹配的範圍是第一行,而 1,addr2 匹配的範圍是整個輸入。
addr1,+N 將匹配addr1和緊接着addr1的n行。
6,+4 = 6,10
6,+2 = 6,8
addr1,~N 將匹配addr1和接下來的行,直到行號是n的倍數。
6,~5 = 6,10
6,~4 = 6,8
s命令的GNU擴展
在替換文本中能夠包含一個特殊序列,由反斜槓引導一個字母組成。說明以下
\L 轉換替換文本到小寫格式直到 \U 或者 \E 出現
\l 轉換下一個字符到小寫格式
\U 轉換替換文到大寫格式直到 \L 或者 \E 出現
\u 轉換下一個字符到大寫格式
\E 中止由 \L 或者 \U 開啓的大小寫轉換
s命令後邊能夠跟以下標誌
g 應用替換到全部匹配正則表達式的內容,不單單是第一個。
number 只替換第n個匹配。
p 執行完替換,打印新的模式空間。
w file-name
執行完替換,寫結果到命名的文件。
e 該命令容許從shell命令管道輸入模式空間。
I
i
正則表達式匹配時忽略大小寫。
M
m
大意是說^在匹配行首時,是從第0個位置開始仍是從第一個字符開始?在有縮進的狀況下。可是好像並無測驗出什麼?