Linux 命令 & shell 腳本之10(學(xué)習(xí)sed編輯器)

sed編輯器會執(zhí)行下列操作
(1) 一次從輸入中讀取一行數(shù)據(jù)。
(2) 根據(jù)所提供的編輯器命令匹配數(shù)據(jù)。
(3) 按照命令修改流中的數(shù)據(jù)。
(4) 將新的數(shù)據(jù)輸出到STDOUT。

sed命令的格式如下。
sed options script file

sed命令選項(xiàng)

選 項(xiàng) 描 述
-e script 在處理輸入時(shí),將script中指定的命令添加到已有的命令中
-f file 在處理輸入時(shí),將file中指定的命令添加到已有的命令中
-n 不產(chǎn)生命令輸出,使用print命令來完成輸出

script參數(shù)指定了應(yīng)用于流數(shù)據(jù)上的單個(gè)命令。如果需要用多個(gè)命令,要么使用-e選項(xiàng)在命令行中指定,要么使用-f選項(xiàng)在單獨(dú)的文件中指定

  1. 在命令行定義編輯器命令
在sed編輯器中使用了s命令。s命令會用斜線間指定的第二個(gè)文本字符串來替換第一個(gè)文本字符串模
[root@MYSQL8 myshell]# echo "This is old str" | sed 's/old/new/'
This is new str
[root@MYSQL8 myshell]# echo "This is old str" | sed "s/old/new/"
This is new str
[root@MYSQL8 myshell]# echo 'This is old str' | sed 's/old/new/'
This is new str
[root@MYSQL8 myshell]# echo "This is a test" | sed 's/test/big test/'
This is a big test

2.編輯整個(gè)文件

$ cat data1.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/' data1.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.

重要的是,要記住,sed編輯器并不會修改文本文件的數(shù)據(jù)。它只會將修改后的數(shù)據(jù)發(fā)送到STDOUT

在命令行使用多個(gè)編輯器命令,要在sed命令行上執(zhí)行多個(gè)命令時(shí),只要用-e選項(xiàng)就可以了
[root@MYSQL8 myshell]# sed -e 's/brown/green/; s/dog/cat/' data1.txt
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
  1. 從文件中讀取編輯器命令
[root@MYSQL8 myshell]# cat script1.sed
s/brown/green/
s/fox/elephant/
s/dog/cat/

[root@MYSQL8 myshell]# sed -f script1.sed data1.txt
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.
The quick green elephant jumps over the lazy cat.

4.要讓替換命令能夠替換一行中不同地方出現(xiàn)的文本必須使用替換標(biāo)記(substitution flag)

s/pattern/replacement/flags
有4種可用的替換標(biāo)記:
? 數(shù)字,表明新文本將替換第幾處模式匹配的地方;
? g,表明新文本將會替換所有匹配的文本;
? p,表明原先行的內(nèi)容要打印出來;
? w file,將替換的結(jié)果寫到文件中。

將替換標(biāo)記指定為2的結(jié)果就是:sed編輯器只替換每行中第二次出現(xiàn)的匹配模式
[oracle@DB02 myshell]$ cat data4.txt 
--old str is old msg--
--old msg in old str--
--aaa str is aaa msg--

[oracle@DB02 myshell]$  sed 's/old/new/2' data4.txt
--old str is new msg--
--old msg in new str--
--aaa str is aaa msg--

g替換標(biāo)記使你能替換文本中匹配模式所匹配的每處地方
[oracle@DB02 myshell]$  sed 's/old/new/g' data4.txt
--new str is new msg--
--new msg in new str--
--aaa str is aaa msg--

p替換標(biāo)記會打印與替換命令中指定的模式匹配的行(通常會和sed的-n選項(xiàng)一起使用,-n選項(xiàng)將禁止sed編輯器輸出)
將p -n 二者配合使用的效果就是只輸出被替換命令修改過的行
[oracle@DB02 myshell]$  sed -n 's/old/new/p' data4.txt
--new str is old msg--
--new msg in old str--

[oracle@DB02 myshell]$  sed -n 's/old/new/pg' data4.txt
--new str is new msg--
--new msg in new str--

w替換標(biāo)記會產(chǎn)生同樣的輸出(和上面 p),不過會將輸出保存到指定文件中
[oracle@DB02 myshell]$  sed  's/old/new/gw data4_new_txt' data4.txt
--new str is new msg--
--new msg in new str--
--aaa str is aaa msg--

[oracle@DB02 myshell]$ cat data4_new_txt 
--new str is new msg--
--new msg in new str--

[oracle@DB02 myshell]$  sed  -n 's/old/new/gw data4_new2_txt' data4.txt

[oracle@DB02 myshell]$ cat data4_new2_txt 
--new str is new msg--
--new msg in new str--

選擇其他字符來作為替換命令中的字符串分隔符,如 用 “!” 替換 “/” 
[oracle@DB02 myshell]$ cat data5.txt
--my homedir is /home/ag, no /home/xag--
--your home  is /home/yu, no /home/you--

[oracle@DB02 myshell]$  sed 's!/home!/myhome!' data5.txt
--my homedir is /myhome/ag, no /home/xag--
--your home  is /myhome/yu, no /home/you--

[oracle@DB02 myshell]$  sed 's!/home!/myhome!g' data5.txt
--my homedir is /myhome/ag, no /myhome/xag--
--your home  is /myhome/yu, no /myhome/you--

用 “#” 替換 “/”
[oracle@DB02 myshell]$  sed 's#/home#/myhome#g' data5.txt
--my homedir is /myhome/ag, no /myhome/xag--
--your home  is /myhome/yu, no /myhome/you--

5.用行尋址將命令作用于特定行或某些行

在sed編輯器中有兩種形式的行尋址:
? 以數(shù)字形式表示行區(qū)間
? 用文本模式來過濾出行

兩種形式都使用相同的格式來指定地址:
[address]command 
也可以將特定地址的多個(gè)命令分組:
address { 
 command1 
 command2 
 command3 
}

[oracle@DB02 myshell]$ cat data1.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.

1. 數(shù)字方式的行尋址

在命令中指定的地址是單個(gè)行號
[oracle@DB02 myshell]$  sed '2s/dog/cat/' data1.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.

使用了行地址區(qū)間(逗號以及結(jié)尾行號指定的一定區(qū)間范圍內(nèi)的行)
[oracle@DB02 myshell]$ sed '1,3s/dog/cat/' data1.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 dog.

將命令作用到文本中從某行開始的所有行,可以用特殊地址——美元符
[oracle@DB02 myshell]$  sed '2,$s/dog/cat/' data1.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 cat.
The quick brown fox jumps over the lazy cat.

2. 使用文本模式過濾器
sed編輯器允許指定文本模式來過濾出命令要作用的行。格式如下:
/pattern/command 
必須用正斜線將要指定的pattern封起來。sed編輯器會將該命令作用到包含指定文本模式的行上。

如下將含有 “in” 的行中 old 替換為 new
[oracle@DB02 myshell]$ sed '/in/s/old/new/g' data4.txt
--old str is old msg--
--new msg in new str--
--aaa str is aaa msg--

3. 命令組合
[oracle@DB02 myshell]$ sed '2{
> s/fox/elephant/
>  s/dog/cat/
>  }' data1.txt

The quick brown fox jumps over the lazy dog.
The quick brown elephant jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.

[oracle@DB02 myshell]$ cat script3.sed
2{
 s/fox/elephant/
 s/dog/cat/
}

[oracle@DB02 myshell]$ sed -f script3.sed data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown elephant jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.

6.刪除行(sed編輯器不會修改原始文件。刪除的行只是從sed編輯器的輸出中消失了)

刪除命令d名副其實(shí),它會刪除匹配指定尋址模式的所有行

[oracle@DB02 myshell]$ cat data6.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.

通過行號指定(第3行)
[oracle@DB02 myshell]$  sed '3d' data6.txt
This is line number 一. 
This is line number 二. 
This is line number 四.

通過特定行區(qū)間指定(從第1行到第3行)
[oracle@DB02 myshell]$  sed '1,3d' data6.txt
This is line number 四.

通過特殊的文件結(jié)尾字符(從第1行到最後一行)
[oracle@DB02 myshell]$  sed '2,$d' data6.txt
This is line number 一. 

使用文本模式過濾器
[oracle@DB02 myshell]$ sed '/number 一/d' data6.txt
This is line number 二. 
This is line number 三. 
This is line number 四.

使用兩個(gè)文本模式來刪除某個(gè)區(qū)間內(nèi)的行,指定的第一個(gè)模式會“打開”行刪除功能,
第二個(gè)模式會“關(guān)閉”行刪除功能。sed編輯器會刪除兩個(gè)指定行之間的所有行(包括指定的行)

[oracle@DB02 myshell]$  sed '/一/,/三/d' data6.txt
This is line number 四.


[oracle@DB02 myshell]$ cat data6.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 一 again.
This is line number 二 again.
This is line number 三 again.
This is line number 四 again.

如搜索後再次出現(xiàn) “一” 則繼續(xù)匹配並刪除
[oracle@DB02 myshell]$  sed '/一/,/三/d' data6.txt
This is line number 四.
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 四 again.

7.插入和附加文本

sed編輯器允許向數(shù)據(jù)流插入和附加文本行。兩個(gè)操作的區(qū)別可能比較讓人費(fèi)解:
? 插入(insert)命令(i)會在指定行前增加一個(gè)新行;
? 附加(append)命令(a)會在指定行后增加一個(gè)新行。
這兩條命令的費(fèi)解之處在于它們的格式。它們不能在單個(gè)命令行上使用。你必須指定是要將
行插入還是附加到另一行。格式如下:
sed '[address]command\ 
new line' 
new line中的文本將會出現(xiàn)在sed編輯器輸出中你指定的位置。記住,當(dāng)使用插入命令時(shí),
文本會出現(xiàn)在數(shù)據(jù)流文本的前面。

使用插入命令時(shí),文本會出現(xiàn)在數(shù)據(jù)流文本的前面。
[oracle@DB02 myshell]$  echo "Test Line 2" | sed 'i\Test Line 1'
Test Line 1
Test Line 2

使用附加命令時(shí),文本會出現(xiàn)在數(shù)據(jù)流文本的后面
[oracle@DB02 myshell]$  echo "Test Line 2" | sed 'a\Test Line 1'
Test Line 2
Test Line 1


[oracle@DB02 myshell]$ head -n 4 data6.txt > data6_new.txt

[oracle@DB02 myshell]$ cat data6_new.txt 
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.

在含有 “number 三” 的前面插入一行
[oracle@DB02 myshell]$ sed '/number 三/i\
>  This is an inserted line.' data6_new.txt
This is line number 一. 
This is line number 二. 
 This is an inserted line.
This is line number 三. 
This is line number 四.

將一個(gè)新行插入到數(shù)據(jù)流第三行前
[oracle@DB02 myshell]$ sed '3i\
> This is an inserted line.' data6_new.txt
This is line number 一. 
This is line number 二. 
This is an inserted line.
This is line number 三. 
This is line number 四.

[oracle@DB02 myshell]$ cat data6_new.txt 
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.

使用 sed 腳本
[oracle@DB02 myshell]$ cat script6.sed
3i This is an inserted line.

[oracle@DB02 myshell]$ sed -f script6.sed data6_new.txt
This is line number 一. 
This is line number 二. 
This is an inserted line.
This is line number 三. 
This is line number 四.

將一個(gè)新行附加到數(shù)據(jù)流中第三行后
[oracle@DB02 myshell]$ sed '3a\
>  This is an appended line.' data6_new.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
 This is an appended line.
This is line number 四.

將新行附加到數(shù)據(jù)流的末尾,只要用代表數(shù)據(jù)最后一行的美元符就可以
[oracle@DB02 myshell]$ sed '$a\
> This is a new line of text.' data6_new.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.
This is a new line of text.

在數(shù)據(jù)流起始位置增加一個(gè)新行。只要在第一行之前插入新行即可。
要插入或附加多行文本,就必須對要插入或附加的新文本中的每一行使用反斜線,直到最后一行
[oracle@DB02 myshell]$ sed '1i\
> This is one line of new text.\
> This is another line of new text.' data6_new.txt
This is one line of new text.
This is another line of new text.
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.

8.修改行

修改(change)命令允許修改數(shù)據(jù)流中整行文本的內(nèi)容。它跟插入和附加命令的工作機(jī)制一樣,你必須在sed命令中單獨(dú)指定新行

sed編輯器會修改第三行中的文本
[oracle@DB02 myshell]$ sed '3c\
> This is a changed line of text.' data6_new.txt
This is line number 一. 
This is line number 二. 
This is a changed line of text.
This is line number 四.

可以用文本模式來尋址
[oracle@DB02 myshell]$ sed '/number 三/c\
> This is a changed line of text.' data6_new.txt
This is line number 一. 
This is line number 二. 
This is a changed line of text.
This is line number 四.

在修改命令中使用地址區(qū)間(會用這一行文本來替換數(shù)據(jù)流中的兩行文本,而不是逐一修改這兩行文本)
[oracle@DB02 myshell]$  sed '2,3c\
> This is a new line of text.' data6_new.txt
This is line number 一. 
This is a new line of text.
This is line number 四.

9.轉(zhuǎn)換命令
(轉(zhuǎn)換命令是一個(gè)全局命令,它會文本行中找到的所有指定字符自動進(jìn)行轉(zhuǎn)換,不會考慮它們出現(xiàn)的位置)

轉(zhuǎn)換(transform)命令(y)是唯一可以處理單個(gè)字符的sed編輯器命令。轉(zhuǎn)換命令格式如下:
[address]y/inchars/outchars/ 
轉(zhuǎn)換命令會對inchars和outchars值進(jìn)行一對一的映射。inchars中的第一個(gè)字符會被轉(zhuǎn)
換為outchars中的第一個(gè)字符,第二個(gè)字符會被轉(zhuǎn)換成outchars中的第二個(gè)字符。這個(gè)映射過
程會一直持續(xù)到處理完指定字符。如果inchars和outchars的長度不同,則sed編輯器會產(chǎn)生一
條錯誤消息。

將 一、二、三 轉(zhuǎn)換成 1、2、3
[oracle@DB02 myshell]$ sed 'y/一二三/123/' data6_new.txt
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 四.

10.打印數(shù)據(jù)流中的信息

? p命令用來打印文本行;
? 等號(=)命令用來打印行號;
? l(小寫的L)命令用來列出行。

1. 打印行
[oracle@DB02 myshell]$ echo "this is a test" | sed 'p'
this is a test
this is a test

是打印包含匹配文本模式的行
[oracle@DB02 myshell]$ sed -n '/number 三/p' data6_new.txt
This is line number 三. 

在命令行上用-n選項(xiàng),你可以禁止輸出其他行,只打印包含匹配文本模式的行。也可以用它來快速打印數(shù)據(jù)流中的某些行
[oracle@DB02 myshell]$  sed -n '1,3p' data6_new.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 

[oracle@DB02 myshell]$  sed -n 2p data6_new.txt
This is line number 二. 

在修改之前查看行,也可以使用打印命令,比如與替換或修改命令一起使用。可以創(chuàng)建一個(gè)腳本在修改行之前顯示該行
[oracle@DB02 myshell]$ cat script3.sed
2{
 p
 s/fox/elephant/
 s/dog/cat/p
}

[oracle@DB02 myshell]$ sed -n -f script3.sed data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown elephant jumps over the lazy cat.

2. 打印行號
[oracle@DB02 myshell]$ sed '=' data6_new.txt 
1
This is line number 一. 
2
This is line number 二. 
3
This is line number 三. 
4
This is line number 四.

[oracle@DB02 myshell]$ sed -n '/number 三/=' data6_new.txt
3

[oracle@DB02 myshell]$ sed -n '/number 三/{
> =
> p
> }' data6_new.txt
3
This is line number 三.

3. 列出行(列出(list)命令(l)可以打印數(shù)據(jù)流中的文本和不可打印的ASCII字符)
[oracle@DB02 myshell]$  sed -n 'l' data6_new.txt
This is line number \344\270\200. $
This is line number \344\272\214. $
This is line number \344\270\211. $
This is line number \345\233\233.$

11.使用 sed 處理文件

1. 寫入文件
w命令用來向文件寫入行。該命令的格式如下:
[address]w filename

將數(shù)據(jù)流中的前兩行打印到一個(gè)文本文件data6_tmp.txt中
[oracle@DB02 myshell]$ sed -n '1,2w data6_tmp.txt' data6.txt

[oracle@DB02 myshell]$ cat data6_tmp.txt
This is line number 一. 
This is line number 二.

[oracle@DB02 myshell]$ sed -n '/number 三/w data6_tmp.txt' data6.txt

[oracle@DB02 myshell]$ cat data6_tmp.txt
This is line number 三. 
This is line number 三 again.

2. 從文件讀取數(shù)據(jù)
讀取(read)命令(r)允許你將一個(gè)獨(dú)立文件中的數(shù)據(jù)插入到數(shù)據(jù)流中。
讀取命令的格式如下:
[address]r filename

[root@MYSQL8 myshell]# cat data12.txt 
This is an added line.
This is the second added line.

將 data12.txt 文件內(nèi)容 插入到 data6_new.txt 的第3行后
[root@MYSQL8 myshell] sed '3r data12.txt' data6_new.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is an added line.
This is the second added line.
This is line number 四.

在匹配文本模式的行后插入data12.txt 文件內(nèi)容
[root@MYSQL8 myshell] sed '/number 二/r data12.txt' data6_new.txt
This is line number 一. 
This is line number 二. 
This is an added line.
This is the second added line.
This is line number 三. 
This is line number 四.

在數(shù)據(jù)流的末尾添加文本,只需用美元符地址符就行
[root@MYSQL8 myshell] sed '$r data12.txt' data6_new.txt
This is line number 一. 
This is line number 二. 
This is line number 三. 
This is line number 四.
This is an added line.
This is the second added line.


[root@MYSQL8 myshell] cat notice.std
Would the following people:
LIST
please report to the ship captain.

[root@MYSQL8 myshell] cat data11.txt
Blum, R Browncoat
Harken, C Alliance

讀取命令的另一個(gè)很酷的用法是和刪除命令配合使用:利用另一個(gè)文件中的數(shù)據(jù)來替換文件中的占位文本
[root@MYSQL8 myshell] sed '/LIST/{
> r data11.txt
> d
> }' notice.std
Would the following people:
Blum, R Browncoat
Harken, C Alliance
please report to the ship captain.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容