1. 程式人生 > 其它 >linux 編輯器_Linux 流編輯器 sed 詳解

linux 編輯器_Linux 流編輯器 sed 詳解

技術標籤:linux 編輯器sed 替換sed 替換檔案內容安卓bin韌體檔案編輯器

作者:tongye

連結:https://www.cnblogs.com/tongye/p/10665771.html

一、流編輯器 sed 與命令 sed

Linux 中,常使用流編輯器 sed 進行文字替換工作。與常使用的互動式編輯器(如vim)不同,sed 編輯器以批處理的方式來編輯檔案,這比互動式編輯器快得多,可以快速完成對資料的編輯修改。

一般來說,sed 編輯器會執行以下操作:

1)一次從輸入中讀取一行資料;

2)根據所提供的編輯器命令匹配資料;

3)按照命令修改流中的資料;

4)將新的資料輸出到 STDOUT。

在 sed 編輯器匹配完一行資料後,它會讀取下一行資料並重復這個過程,直到處理完所有資料。使用 sed 命令開啟一個 sed 編輯器。sed 命令的格式如下:

sed[options]edit_commands[file]    #[]中的內容為可選可不選

其中,options 為命令選項,選擇不同的 options 可以修改 sed 命令的行為,主要有 3 個選項:

1)-e 選項:在處理輸入時,將 script 中指定的編輯命令新增到已有的命令中。通俗的說,就是在 sed 後面直接新增編輯命令:

sed-e'edit_commands'[files]

sed 命令在預設情況下使用的是 -e 選項。當只有一個編輯命令時,-e 選項可以省略;但是當要在一條 sed 語句中執行多個編輯命令時,就需要使用 -e 選項了:

sed-e's/root/ROOT/g;s/bin/BIN/g'/etc/passwd  #使用sed同時執行兩條編輯命令(本文大部分用例都直接使用/etc/passwd檔案)

sed-e's/root/ROOT/g'-e's/bin/BIN/g'/etc/passwd  #使用sed同時執行兩條編輯命令

2)-f 選項:在處理輸入時,將 file 中指定的編輯命令新增到已有的命令中:

前面提到,在需要同時執行多條編輯命令時,可以使用 -e 選項。但是當所需要執行的編輯命令數量很多時,每次使用 sed 時一行一行地敲顯然不是很方便,這時可以將所用到的 sed 編輯命令寫入一個檔案,然後使用 sed -f 選項來指定讀取該檔案:

$catscript.sed
$s/root/ROOT/
$s/bin/BIN/
$s/home/HOME/
sed-fscript.sed/etc/passwd

3)-n 選項:不產生命令輸入:

sed-n's/root/ROOT/'/etc/passwd

使用 -n 選項不會將流編輯器的內容輸出到 STDOUT,通常將 -n 選項與 p 命令結合起來使用,以只打印被匹配的行。

除了這三個選項外,sed 編輯器還提供了許多命令,用來進行更詳細的操作,簡單列一下,後面再仔細介紹:

命令描述
s文字替換操作
d刪除操作
i插入操作
a附加操作
c將一行文字修改為新的行
y逐字元替換
p列印文字行
=列印行號
w向檔案中寫入資料
r從檔案中讀取資料

二、使用 sed 命令進行文字替換

sed 使用 s 命令來進行文字替換操作,基本格式如下:

sed's/srcStr/dstStr/'file

其中,srcStr 為想要替換的文字,dstStr 為將要替換成的文字。使用 s 命令時,sed 編輯器會在一行一行地讀取檔案 file,並在每行查詢文字 srcStr,如果找到了,則將該處的 srcStr 替換為 dstStr。

/ 字元為界定符,用於分隔字串(sed 編輯器允許使用其他字元作為替換命令中的字串分隔符):

sed's!/bin/bash!/BIN/BASH!'/etc/passwd#使用!作為字串分隔符

預設情況下,替換命令只會替換掉目標文字在每行中第一次出現的地方。若想要替換掉每行中所有匹配的地方,可以使用替換標記 g。替換標記放在編輯命令的末尾。除了 g 外,還有幾種替換標記:

1)數字:指明替換掉第幾次匹配到的文字,沒有設定這個標記時,預設是替換第一次匹配的文字:

sed's/root/ROOT/2'/etc/passwd

這行命令將 /etc/passwd 檔案中每行的第 2 個 root 替換為 ROOT;

2)g:替換所有匹配到的文字:

sed's/root/ROOT/g'/etc/passwd

這行命令將 /etc/passwd 檔案中的 root,全部替換為 ROOT;

3)p:列印與替換命令中指定模式(srcStr)相匹配的行:

sed's/root/ROOT/p'/etc/passwd

執行這命令,會在 STDOUT 上看到包含有 root 的行被輸出了兩次,一次是 sed 編輯器自動輸出的;另一次則是 p 標記打印出來的匹配行。

單獨地使用 p 標記沒什麼用處,通常將 p 標記和 -n 選項結合起來使用,這樣就可以只輸出被匹配替換過的行了:

ed-n's/root/ROOT/gp'/etc/passwd    #將/etc/passwd中所有的root都替換成ROOT,並輸出被修改的行

注:可以使用 " = " 命令來列印行號,用法與 p 一樣。 

4)w file:將替換的結果寫到檔案中,不過只儲存被修改的行,與 -n + p 的功能類似:

sed-n's/root/ROOT/gwchange.txt'/etc/passwd    #將/etc/passwd中所有的root都替換成ROOT,並將被修改的行儲存到檔案change.txt中去

三、使用行定址對特定行進行編輯

預設情況下,sed 編輯器會對檔案中的所有行進行編輯。當然,也可以只指定特定的某些行號,或者行範圍來進行流編輯,這需要用到行定址。所指定的行地址放在編輯命令之前:

[address]commands

3.1 使用數字方式進行行定址

sed 編輯器將文字流中的每一行都進行編號,第一行的編號為 1 ,後面的按順序分配行號。通過指定特定的行號,可以選擇編輯特定的行。舉幾個例子:

sed'3s/bin/BIN/g'/etc/passwd    #將第3行中所有的bin替換成BIN

sed'2,5s/bin/BIN/g'/etc/passwd  #將第2到5行中所有的bin替換成BIN

sed'10,$s/bin/BIN/g'/etc/passwd  #將第10行到最後一行中所有的bin替換成BIN

注:行定址不止對替換命令有效,對其他命令也都是有效的,後面也會用到。

3.2 使用文字模式過濾器過濾行

sed 編輯器允許指定文字模式來過濾出命令要作用的行,格式如下:

/pattern/command

必須使用斜槓符 " / " 將要指定的文字模式 pattern 包含起來。sed 編輯器會尋找匹配文字模式的行,然後對這些行執行編輯命令:

sed-n'/root/s/bin/BIN/p'/etc/passwd#尋找包含有字串root的行,並將匹配行的bin替換為BIN

與數字定址一樣,也可以使用文字過濾區間來過濾行:

sed'/pattern1/,/pattern2/edit_command'file

這行命令會在檔案 file 中先尋找匹配 pattern1 的行,然後從該行開始,執行編輯命令,直到找到匹配 pattern2 的行。但是需要注意的是,使用文字區間過濾文字時,只要匹配到了開始模式(pattern1),編輯命令就會開始執行,直到匹配到結束模式(pattern2),這會導致一種情況:一個文字中,先匹配到了一對 pattern1、pattern2,對該文字區間中的文字執行了編輯命令;然後,在 pattern2 之後又匹配到了 pattern1,這時就會再次開始執行編輯命令,因此,在使用文字區間過濾時要格外小心。舉個例子:

sed-n'/root/,/nologin/s/bin/BIN/p'/etc/passwd

這行命令對 /etc/passwd 進行了兩次文字區間匹配,結果如下:

dd27f93bee53c42ddd7209d3a1b24980.png

四、使用 sed 命令刪除行

sed 編輯器使用 d 命令來刪除文字流中的特定行。使用 d 命令時,一般需要帶上位定址,以刪除指定的行,否則預設會刪除所有文字行:

sed'/root/d'/etc/passwd #刪除匹配root的行

sed'2,$d'/etc/passwd    #刪除第2到最後一行

五、使用 sed 命令插入和附加文字

sed 編輯器使用 i 命令來向資料流中插入文字行,使用 a 命令來向資料流中附加文字行。其中:i 命令會在指定行前增加一個新行;a 命令會在指定行後增加一個新行。

需要注意的是,這兩個命令都不能在單個命令列上使用(即不是用來在一行中插入或附加一段文字的),只能指定插入還是附加到另一行。命令格式如下:

sed'[address][i|a]\newline'file

newline 中的文字即為將要插入或附加在一行前面或後面的文字。常常使用這兩個命令結合行定址在特定的行前面或後面增加一個新行。舉個例子:

sed'i\Insertalinebehindeveryline'/etc/passwd      #向資料流的每一行前面增加一個新行,新行的內容為\後面的內容

sed'1i\Insertalinebehindthefirstline'/etc/passwd   #在資料流的第一行前面增加一個新行

sed'3a\Appendalineafterthethirdline'/etc/passwd#在資料流的第三行後面增加一個新行
    
sed'$a\Appendalineinthelastline'/etc/passwd      #在資料流的最後一行後面增加一個新行

六、使用 sed 命令修改行

使用命令 c 可以將資料流中的整行文字修改為新的行,與插入、附加操作一樣,這要求在 sed 命令中指定新的行,格式如下:

sed'[address][c]\newtext'file

newtext 中的文字為匹配行將要被修改成的文字。

sed'3c\Newtext'/etc/passwd     #將資料流中第三行的內容修改為\後面的內容

sed'/root/c\Newtext'/etc/passwd  #將匹配到root的行的內容修改為\後面的內容

sed'2,4c\Newtext'/etc/passwd    #將第2到4行的內容修改為\後面的內容,但是不是逐行修改,而是會將這之間的3行用一行文字來替代

注意這裡對地址區間使用 c 命令進行修改時,不會逐行修改,而是會將整個區間用一行修改文字替代。

七、使用 sed 命令逐字元轉換

使用 y 引數可以按要求對文字進行逐字元轉換。格式如下:

[address]y/inchars/outchars/

轉換命令會對 inchars 和 outchars 的值進行一對一的對映。inchars 中的第一個字元會被轉換成 outchars 中的第一個字元;inchars 中的第二個字元會被轉換成 outchars 中的第二個字元;... 直到處理完一行。如果 inchars 和 outchars 的長度不同,則 sed 編輯器會產生一個錯誤訊息。舉個例子:

echoabcdefggfedcba|sed'y/acg/ACG/'

輸出結果為 AbCdefGGfedCbA。

八、使用 sed 命令處理檔案

8.1 向檔案中寫入資料

前面已經提到過,可以使用 w 命令向檔案寫入行。格式如下:

[address]wfilename

舉個例子:

sed'1,2wtest.txt'/etc/passwd

該語句將資料流的第 1、2 行寫入檔案 test.txt 中去。

8.2 從檔案中讀取資料

可以使用 r 命令來將一個文字中的資料插入到資料流中去,與普通的插入命令 i 類似,這也是對行進行操作的,命令格式如下:

[address]rfilename

filename 為要插入的檔案。r 命令常結合行定址使用,以將文字插入到指定的行後面。舉個例子:

sed'3rtest.txt'/etc/passwd

這句話將檔案 test.txt 中的內容插入到資料流第三行後面去。

參考書籍:

《Linux命令列與shell指令碼程式設計大全》 (第3版)

《Shell指令碼學習指南》


●編號778,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

6c8947c42bb18d8b4b7cf3f3fba2e9ce.png

運維

更多推薦25個技術類公眾微信

涵蓋:程式人生、演算法與資料結構、黑客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。