結(jié)合自己使用需要,主要根據(jù)三十分鐘學(xué)會(huì)SED簡(jiǎn)化整理所得个盆。
用途
sed是一個(gè)文本解析轉(zhuǎn)換工具脖岛,主要用于以下用途:
- 文本替換
- 選擇性的輸出文本文件
- 從文本文件的某處開始編輯
- 無交互式的對(duì)文本文件進(jìn)行編輯等
工作流
SED遵循簡(jiǎn)單的工作流:讀取嚷那,執(zhí)行和顯示击碗。
讀取: SED從輸入流(文件,管道或者標(biāo)準(zhǔn)輸入)中讀取一行并且存儲(chǔ)到它叫做 模式空間(pattern buffer)的內(nèi)部緩沖區(qū)
執(zhí)行: 默認(rèn)情況下,所有的SED命令都在模式空間中順序的執(zhí)行编兄,除非指定了行的地址,否則SED命令將會(huì)在所有的行上依次執(zhí)行
顯示: 發(fā)送修改后的內(nèi)容到輸出流声登。在發(fā)送數(shù)據(jù)之后狠鸳,模式空間將會(huì)被清空。
在文件所有的內(nèi)容都被處理完成之前悯嗓,上述過程將會(huì)重復(fù)執(zhí)行
注意事項(xiàng)
- 模式空間 (pattern buffer) 是一塊活躍的緩沖區(qū)件舵,在sed編輯器執(zhí)行命令時(shí)它會(huì)保存待檢查的文本
- 默認(rèn)情況下,所有的SED命令都是在模式空間中執(zhí)行脯厨,因此輸入文件并不會(huì)發(fā)生改變
- 還有另外一個(gè)緩沖區(qū)叫做** 保持空間** (hold buffer)铅祸,在處理模式空間中的某些行時(shí),可以用保持空間來臨時(shí)保存一些行。在每一個(gè)循環(huán)結(jié)束的時(shí)候临梗,SED將會(huì)移除模式空間中的內(nèi)容涡扼,但是該緩沖區(qū)中的內(nèi)容在所有的循環(huán)過程中是持久存儲(chǔ)的。SED命令無法直接在該緩沖區(qū)中執(zhí)行盟庞,因此SED允許數(shù)據(jù)在 **保持空間 **和 模式空間之間切換
- 初始情況下吃沪,保持空間 和** 模式空間** 這兩個(gè)緩沖區(qū)都是空的
- 如果沒有提供輸入文件的話,SED將會(huì)從標(biāo)準(zhǔn)輸入接收請(qǐng)求
- 如果沒有提供地址范圍的話什猖,默認(rèn)情況下SED將會(huì)對(duì)所有的行進(jìn)行操作
基礎(chǔ)語(yǔ)法
sed [-n] [-e] 'command(s)' files
sed [-n] -f scriptfile files
第一種方式在命令行中使用單引號(hào)指定要執(zhí)行的命令票彪,第二種方式則指定了包含SED命令的腳本文件。
標(biāo)準(zhǔn)選項(xiàng)
- -n:默認(rèn)情況下不狮,模式空間中的內(nèi)容在處理完成后將會(huì)打印到標(biāo)準(zhǔn)輸出降铸,該選項(xiàng)用于阻止該行為
$ sed '' hello.txt #創(chuàng)建個(gè)hello的txt,''表示沒輸入任何命令
hello
$ sed -n '' hello.txt
- -e:指定要執(zhí)行的命令摇零,使用該參數(shù)垮耳,我們可以指定多個(gè)命令,讓我們打印每一行兩次:
$ sed -e '' -e 'p' hello.txt
hello
hello
- -f: 指定包含要執(zhí)行的命令的腳本文件
$ echo "p" > commands
$
$ sed -n -f commands hello.txt
hello
行尋址
默認(rèn)情況下遂黍,在SED中使用的命令會(huì)作用于文本數(shù)據(jù)的所有行终佛。如果只想將命令作用于特定的行或者某些行,則需要使用 行尋址 功能雾家。
[address]command #基本語(yǔ)法
先創(chuàng)建一個(gè)文本用于演示.
$ cat demo.txt
1 one
2 two
3 three
4 four
5 five
6 six
1.以數(shù)字形式表示的行區(qū)間
指定行铃彰。
$ sed -n '3p' demo.txt #p命令是打印出模式空間中的內(nèi)容
3 three
用逗號(hào)確定范圍
$ sed -n '2,4p' demo.txt
2 two
3 three
4 four
$符號(hào)表示最后一行
$ sed -n '4,$ p' demo.txt
4 four
5 five
6 six
SED還提供了另外兩種操作符用于指定地址范圍,第一個(gè)是加號(hào)(+)操作符芯咧,它可以與逗號(hào)(,)操作符一起使用牙捉,例如 M, +n 將會(huì)打印出從第M行開始的下n行
$ sed -n '2,+2p' demo.txt
2 two
3 three
4 four
我們還可以使用波浪線操作符()指定地址范圍,它使用MN的形式敬飒,它告訴SED應(yīng)該處理M行開始的每N行邪铲。例如,50~5匹配行號(hào)50无拗,55带到,60,65等英染,讓我們只輸出文件中的奇數(shù)行
$ sed -n '1~2p' demo.txt
1 one
3 three
5 five
注意揽惹,如果使用的是Mac系統(tǒng)自帶的sed命令,可能不支持~和+操作符四康√虏可以使用brew install gnu-sed --with-default-names重新安裝GNU-SED。
2.使用文本過濾器
/pattern/command #一般格式
$ sed -n '/three/ p' demo.txt
3 three
規(guī)則與數(shù)字表示一樣闪金,也可以與數(shù)字表示配合使用.
$ sed -n '/one/,/three/ p' demo.txt
1 one
2 two
3 three
$ sed -n '/3/ p' demo.txt
3 three
基本命令
- 刪除命令 d
[address1[,address2]]d
address1和address2是開始和截止地址疯溺,它們可以是行號(hào)或者字符串匹配模式,這兩種地址都是可選的。
注意的是囱嫩,該命令只會(huì)移除模式空間中的行嗅辣,但原始內(nèi)容不會(huì)改變。
$ sed '3,5 d' demo.txt
1 one
2 two
6 six
- 文件寫入命令 w
SED提供了 write 命令用于將模式空間中的內(nèi)容寫入到文件
$ sed -n '2,3 w junk.txt' demo.txt
$ cat junk.txt
2 two
3 three
- 追加命令 a
[address]a Append text
$ sed '2 a 9 nine' demo.txt
1 one
2 two
9 nine
3 three
4 four
5 five
6 six
-
插入命令 i
與a相同挠说,不過是在匹配的位置前增加一行澡谭。 - 行替換命令 c
SED通過 c 提供了 change 和 replace 命令,該命令幫助我們使用新文本替換已經(jīng)存在的行损俭,當(dāng)提供行的地址范圍時(shí)蛙奖,所有的行都被作為一組被替換為單行文本
$ sed '3,5 c 9 nine' demo.txt
1 one
2 two
9 nine
6 six
- 替換命令 s
[address1[,address2]]s/pattern/replacement/[flags]
$ sed 's/one/first/' demo.txt
1 first
2 two
3 three
4 four
5 five
6 six
在SED中,使用替換命令的時(shí)候默認(rèn)只會(huì)對(duì)第一個(gè)匹配的位置進(jìn)行替換.
以下有一些參數(shù)可供使用杆兵。
g對(duì)所有匹配的內(nèi)容進(jìn)行替換雁仲。
數(shù)字n: 只替換第n次匹配。
p:只輸出改變的行琐脏。
w:存儲(chǔ)改變的行到文件攒砖。比如
sed 's/one/first/w demoCopy.txt' demo.txt
i:匹配時(shí)忽略大小寫。
排除命令 !
$ sed -n '/two/ !p' demo.txt
1 one
3 three
4 four
5 five
6 six
保持空間
在處理模式空間中的某些行時(shí)日裙,可以用保持空間來臨時(shí)保存一些行吹艇。有5條命令可用來操作保持空間
命令 | 作用 |
---|---|
h | 將模式空間復(fù)制到保持空間 |
H | 將模式空間附加到保持空間 |
g | 將保持空間復(fù)制到模式空間 |
G | 將保持空間附加到模式空間 |
x | 交換模式空間和保持空間的內(nèi)容 |
$ sed -n '1!G;h;$p' demo.txt
6 six
5 five
4 four
3 three
2 two
1 one
- 1!G 這句的意思是出了第一行之外,處理每一行的時(shí)候都將保持空間中的內(nèi)容追加到模式空間(正序->倒序)
- h 將模式空間中的內(nèi)容復(fù)制到保持空間以備下一行匹配的時(shí)候追加到下一行的后面
- $p 如果匹配到最后一行的話則輸出模式空間中的內(nèi)容
- 上述步驟不斷重復(fù)直到文本結(jié)束剛好將文件內(nèi)容翻轉(zhuǎn)了一次