6.8 Linux sed(Linux三劍客之一)

      網友投稿 894 2025-04-01

      我們知道,Vim 采用的是交互式文本編輯模式,你可以用鍵盤命令來交互性地插入、刪除或替換數據中的文本。但本節要講的 sed 命令不同,它采用的是流編輯模式,最明顯的特點是,在 sed 處理數據之前,需要預先提供一組規則,sed 會按照此規則來編輯數據。


      sed 會根據腳本命令來處理文本文件中的數據,這些命令要么從命令行中輸入,要么存儲在一個文本文件中,此命令執行數據的順序如下:

      每次僅讀取一行內容;

      根據提供的規則命令匹配并修改數據。注意,sed 默認不會直接修改源文件數據,而是會將數據復制到緩沖區中,修改也僅限于緩沖區中的數據;

      將執行結果輸出。

      當一行數據匹配完成后,它會繼續讀取下一行數據,并重復這個過程,直到將文件中所有數據處理完畢。

      sed 命令的基本格式如下:

      [root@localhost ~]# sed [選項] [腳本命令] 文件名

      該命令常用的選項及含義,如表 1 所示。

      成功使用 sed 命令的關鍵在于掌握各式各樣的腳本命令及格式,它能幫你定制編輯文件的規則。

      sed腳本命令

      此命令的基本格式為:

      [address]s/pattern/replacement/flags

      其中,address 表示指定要操作的具體行,pattern 指的是需要替換的內容,replacement 指的是要替換的新內容。

      關于指定具體操作行(address)的用法,這里先不做解釋,文章后續會對其做詳細介紹。

      此命令中常用的 flags 標記如表 2 所示。

      比如,可以指定 sed 用新文本替換第幾處模式匹配的地方:

      [root@localhost ~]# sed 's/test/trial/2' data4.txt This is a test of the trial script. This is the second test of the trial script.

      可以看到,使用數字 2 作為標記的結果就是,sed 編輯器只替換每行中第 2 次出現的匹配模式。

      如果要用新文件替換所有匹配的字符串,可以使用 g 標記:

      [root@localhost ~]# sed 's/test/trial/g' data4.txt This is a trial of the trial script. This is the second trial of the trial script.

      我們知道,-n 選項會禁止 sed 輸出,但 p 標記會輸出修改過的行,將二者匹配使用的效果就是只輸出被替換命令修改過的行,例如:

      [root@localhost ~]# cat data5.txt This is a test line. This is a different line. [root@localhost ~]# sed -n 's/test/trial/p' data5.txt This is a trial line.

      w 標記會將匹配后的結果保存到指定文件中,比如:

      [root@localhost ~]# sed 's/test/trial/w test.txt' data5.txt This is a trial line. This is a different line. [root@localhost ~]#cat test.txt This is a trial line.

      在使用 s 腳本命令時,替換類似文件路徑的字符串會比較麻煩,需要將路徑中的正斜線進行轉義,例如:

      [root@localhost ~]# sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd

      此命令的基本格式為:

      [address]d

      如果需要刪除文本中的特定行,可以用 d 腳本命令,它會刪除指定行中的所有內容。但使用該命令時要特別小心,如果你忘記指定具體行的話,文件中的所有內容都會被刪除,舉個例子:

      [root@localhost ~]# 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 [root@localhost ~]# sed 'd' data1.txt \#什么也不輸出,證明成了空文件

      當和指定地址一起使用時,刪除命令顯然能發揮出大的功用。可以從數據流中刪除特定的文本行。

      address 的具體寫法后續會做詳細介紹,這里只給大家舉幾個簡單的例子:

      通過行號指定,比如刪除 data6.txt 文件內容中的第 3 行:

      [root@localhost ~]# cat data6.txt This is line number 1. This is line number 2. This is line number 3. This is line number 4. [root@localhost ~]# sed '3d' data6.txt This is line number 1. This is line number 2. This is line number 4.

      或者通過特定行區間指定,比如刪除 data6.txt 文件內容中的第 2、3行:

      [root@localhost ~]# sed '2,3d' data6.txt This is line number 1. This is line number 4.

      也可以使用兩個文本模式來刪除某個區間內的行,但這么做時要小心,你指定的第一個模式會“打開”行刪除功能,第二個模式會“關閉”行刪除功能,因此,sed 會刪除兩個指定行之間的所有行(包括指定的行),例如:

      [root@localhost ~]#sed '/1/,/3/d' data6.txt \#刪除第 1~3 行的文本數據 This is line number 4.

      或者通過特殊的文件結尾字符,比如刪除 data6.txt 文件內容中第 3 行開始的所有的內容:

      [root@localhost ~]# sed '3,$d' data6.txt This is line number 1. This is line number 2.

      在此強調,在默認情況下 sed 并不會修改原始文件,這里被刪除的行只是從 sed 的輸出中消失了,原始文件沒做任何改變。

      a 命令表示在指定行的后面附加一行,i 命令表示在指定行的前面插入一行,這里之所以要同時介紹這 2 個腳本命令,因為它們的基本格式完全相同,如下所示:

      [address]a(或 i)\新文本內容

      下面分別就這 2 個命令,給讀者舉幾個例子。比如說,將一個新行插入到數據流第三行前,執行命令如下:

      [root@localhost ~]# sed '3i\ \> This is an inserted line.' data6.txt This is line number 1. This is line number 2. This is an inserted line. This is line number 3. This is line number 4.

      再比如說,將一個新行附加到數據流中第三行后,執行命令如下:

      [root@localhost ~]# sed '3a\ \> This is an appended line.' data6.txt This is line number 1. This is line number 2. This is line number 3. This is an appended line. This is line number 4.

      如果你想將一個多行數據添加到數據流中,只需對要插入或附加的文本中的每一行末尾(除最后一行)添加反斜線即可,例如:

      [root@localhost ~]# sed '1i\ \> This is one line of new text.\ \> This is another line of new text.' data6.txt This is one line of new text. This is another line of new text. This is line number 1. This is line number 2. This is line number 3. This is line number 4.

      可以看到,指定的兩行都會被添加到數據流中。

      c 命令表示將指定行中的所有內容,替換成該選項后面的字符串。該命令的基本格式為:

      [address]c\用于替換的新文本

      舉個例子:

      [root@localhost ~]# sed '3c\ \> This is a changed line of text.' data6.txt This is line number 1. This is line number 2. This is a changed line of text. This is line number 4. 在這個例子中,sed 編輯器會修改第三行中的文本,其實,下面的寫法也可以實現此目的: [root@localhost ~]# sed '/number 3/c\ \> This is a changed line of text.' data6.txt This is line number 1. This is line number 2. This is a changed line of text. This is line number 4.

      y 轉換命令是唯一可以處理單個字符的 sed 腳本命令,其基本格式如下:

      [address]y/inchars/outchars/

      轉換命令會對 inchars 和 outchars 值進行一對一的映射,即 inchars 中的第一個字符會被轉換為 outchars 中的第一個字符,第二個字符會被轉換成 outchars 中的第二個字符…這個映射過程會一直持續到處理完指定字符。如果 inchars 和 outchars 的長度不同,則 sed 會產生一條錯誤消息。

      舉個簡單例子:

      [root@localhost ~]# sed 'y/123/789/' data8.txt This is line number 7. This is line number 8. This is line number 9. This is line number 4. This is line number 7 again. This is yet another line. This is the last line in the file.

      可以看到,inchars 模式中指定字符的每個實例都會被替換成 outchars 模式中相同位置的那個字符。

      轉換命令是一個全局命令,也就是說,它會文本行中找到的所有指定字符自動進行轉換,而不會考慮它們出現的位置,再打個比方:

      [root@localhost ~]# echo "This 1 is a test of 1 try." | sed 'y/123/456/' This 4 is a test of 4 try.

      sed 轉換了在文本行中匹配到的字符 1 的兩個實例,我們無法限定只轉換在特定地方出現的字符。

      p 命令表示搜索符號條件的行,并輸出該行的內容,此命令的基本格式為:

      [address]p

      p 命令常見的用法是打印包含匹配文本模式的行,例如:

      [root@localhost ~]# cat data6.txt This is line number 1. This is line number 2. This is line number 3. This is line number 4. [root@localhost ~]# sed -n '/number 3/p' data6.txt This is line number 3.

      可以看到,用 -n 選項和 p 命令配合使用,我們可以禁止輸出其他行,只打印包含匹配文本模式的行。

      如果需要在修改之前查看行,也可以使用打印命令,比如與替換或修改命令一起使用。可以創建一個腳本在修改行之前顯示該行,如下所示:

      [root@localhost ~]# sed -n '/3/{ \> p \> s/line/test/p \> }' data6.txt This is line number 3. This is test number 3.

      sed 命令會查找包含數字 3 的行,然后執行兩條命令。首先,腳本用 p 命令來打印出原始行;然后它用 s 命令替換文本,并用 p 標記打印出替換結果。輸出同時顯示了原來的行文本和新的行文本。

      w 命令用來將文本中指定行的內容寫入文件中,此命令的基本格式如下:

      [address]w filename

      這里的 filename 表示文件名,可以使用相對路徑或絕對路徑,但不管是哪種,運行 sed 命令的用戶都必須有文件的寫權限。

      下面的例子是將數據流中的前兩行打印到一個文本文件中:

      [root@localhost ~]# sed '1,2w test.txt' data6.txt This is line number 1. This is line number 2. This is line number 3. This is line number 4. [root@localhost ~]# cat test.txt This is line number 1. This is line number 2.

      當然,如果不想讓行直接輸出,可以用 -n 選項,再舉個例子:

      [root@localhost ~]# cat data11.txt Blum, R Browncoat McGuiness, A Alliance Bresnahan, C Browncoat Harken, C Alliance [root@localhost ~]# sed -n '/Browncoat/w Browncoats.txt' data11.txt cat Browncoats.txt Blum, R Browncoat Bresnahan, C Browncoat

      可以看到,通過使用 w 腳本命令,sed 可以實現將包含文本模式的數據行寫入目標文件。

      r 命令用于將一個獨立文件的數據插入到當前數據流的指定位置,該命令的基本格式為:

      [address]r filename

      sed 命令會將 filename 文件中的內容插入到 address 指定行的后面,比如說:

      [root@localhost ~]# cat data12.txt This is an added line. This is the second added line. [root@localhost ~]# sed '3r data12.txt' data6.txt This is line number 1. This is line number 2. This is line number 3. This is an added line. This is the second added line. This is line number 4.

      如果你想將指定文件中的數據插入到數據流的末尾,可以使用 $ 地址符,例如:

      [root@localhost ~]# sed '$r data12.txt' data6.txt This is line number 1. This is line number 2. This is line number 3. This is line number 4. This is an added line. This is the second added line.

      q 命令的作用是使 sed 命令在第一次匹配任務結束后,退出 sed 程序,不再進行對后續數據的處理。

      比如:

      [root@localhost ~]# sed '2q' test.txt This is line number 1. This is line number 2.

      可以看到,sed 命令在打印輸出第 2 行之后,就停止了,是 q 命令造成的,再比如:

      [root@localhost ~]# sed '/number 1/{ s/number 1/number 0/;q; }' test.txt This is line number 0.

      使用 q 命令之后,sed 命令會在匹配到 number 1 時,將其替換成 number 0,然后直接退出。

      sed 腳本命令的尋址方式

      6.8 Linux sed(Linux三劍客之一)

      前面在介紹各個腳本命令時,我們一直忽略了對 address 部分的介紹。對各個腳本命令來說,address 用來表明該腳本命令作用到文本中的具體行。

      默認情況下,sed 命令會作用于文本數據的所有行。如果只想將命令作用于特定行或某些行,則必須寫明 address 部分,表示的方法有以下 2 種:

      以數字形式指定行區間;

      用文本模式指定具體行區間。

      以上兩種形式都可以使用如下這 2 種格式,分別是:

      [address]腳本命令

      或者

      address { 多個腳本命令 }

      以上兩種形式在前面例子中都有具體實例,因此這里不再做過多贅述。

      當使用數字方式的行尋址時,可以用行在文本流中的行位置來引用。sed 會將文本流中的第一行編號為 1,然后繼續按順序為接下來的行分配行號。

      在腳本命令中,指定的地址可以是單個行號,或是用起始行號、逗號以及結尾行號指定的一定區間范圍內的行。這里舉一個 sed 命令作用到指定行號的例子:

      [root@localhost ~]#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

      可以看到,sed 只修改地址指定的第二行的文本。下面的例子中使用了行地址區間:

      [root@localhost ~]# sed '2,3s/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 dog 在此基礎上,如果想將命令作用到文本中從某行開始的所有行,可以用特殊地址——美元符($): [root@localhost ~]# 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

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

      /pattern/command

      注意,必須用正斜線將要指定的 pattern 封起來,sed 會將該命令作用到包含指定文本模式的行上。

      舉個例子,如果你想只修改用戶 demo 的默認 shell,可以使用 sed 命令,執行命令如下:

      [root@localhost ~]# grep demo /etc/passwd demo:x:502:502::/home/Samantha:/bin/bash [root@localhost ~]# sed '/demo/s/bash/csh/' /etc/passwd root:x:0:0:root:/root:/bin/bash ... demo:x:502:502::/home/demo:/bin/csh ...

      雖然使用固定文本模式能幫你過濾出特定的值,就跟上面這個用戶名的例子一樣,但其作用難免有限,因此,sed 允許在文本模式使用正則表達式指明作用的具體行。正則表達式允許創建高級文本模式匹配表達式來匹配各種數據。這些表達式結合了一系列通配符、特殊字符以及固定文本字符來生成能夠匹配幾乎任何形式文本的簡練模式。

      收到篇幅的限制,本節僅介紹了 sed 命令每次只讀取一行內容并處理,有關 sed 命令如何一次處理多行文本內容,放到下節繼續講解,讀者可點擊《linux sed命令高級用法》繼續學習。

      linux

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel如何合并同類項(excel如何合并同類項求平均值)
      下一篇:如何把多余的空白頁去了?(怎么把多余的空白頁刪除)
      相關文章
      中文字幕亚洲一区二区三区| 亚洲 欧洲 自拍 另类 校园| 亚洲小说区图片区另类春色| 国产日本亚洲一区二区三区| 亚洲视频一区在线| 国产A在亚洲线播放| 久久亚洲高清综合| 亚洲综合国产一区二区三区| 亚洲综合色在线观看亚洲| 亚洲黄黄黄网站在线观看| 亚洲日韩在线观看| 亚洲国产成人久久精品99 | 亚洲福利在线视频| 亚洲AV人无码激艳猛片| 亚洲国产精品一区| 亚洲视频在线免费播放| 亚洲码在线中文在线观看| 亚洲国产成人九九综合| 亚洲黄色激情视频| 亚洲夂夂婷婷色拍WW47| 亚洲国产aⅴ成人精品无吗| 色五月五月丁香亚洲综合网| 亚洲国产成人久久一区久久 | 亚洲人成免费电影| 国产精品亚洲片夜色在线| 亚洲综合欧美色五月俺也去| 日韩欧美亚洲中文乱码| 亚洲男人的天堂在线va拉文| 亚洲午夜久久久久久噜噜噜| 久久精品国产96精品亚洲 | 亚洲国产精品13p| 亚洲中文字幕在线第六区| 国产成人A人亚洲精品无码| 亚洲精品高清视频| 亚洲a级成人片在线观看| 国产亚洲精品成人AA片| 久久亚洲AV午夜福利精品一区| 亚洲综合无码一区二区| 亚洲乱码一区av春药高潮| 亚洲精品人成网线在线播放va| 高清在线亚洲精品国产二区|