每天一個 Linux 命令:sed 命令

1. 功能簡介

sed(Stream EDitor)是一種流文件編輯器,它一次處理一行內容。

處理時,把當前處理的行存儲在臨時緩衝區中,稱爲 “模式空間”(Pattern Space),接着用 sed 命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕,接着處理下一行,直到文件末尾。

文件內容並沒有改變,除非使用 - i 選項。sed 主要用來編輯一個或多個文件,簡化對文件的反覆操作或者用來編寫轉換程序等。

sed 功能同 awk 類似,差別在於,sed 簡單,對列處理的功能要差一些,awk 功能複雜,對列處理的功能比較強大。

2. 命令格式

sed [OPTION]... {script-only-if-no-other-script} [input-file]...

其中 OPTION 爲命令選項,script-only-if-no-other-script 爲處理動作,可以由 - e 指定,input-file 爲輸入文件,可指定多個。

3. 選項說明

選項:
-n,--quiet,--silent:使用安靜模式。sed的一般用法中,所有來自STDIN的數據一般都會被打印到終端上,如果加上-n後,則只有經過sed特殊處理的那一行纔會被列出來。
-e <script>,--expression=<script>:指定sed動作,可以由多個-e指定多個動作。
-f <script-file>,--file=<script-file>:直接將sed的動作寫在一個文件內,-f filename則可以運行filename 內的sed動作;
-r,--regexp-extended:sed支持擴展正則表達式(默認是基礎正則表達式)。
-i :直接修改讀取的文件內容,而不是輸出到終端。
--help:顯示幫助。
--version:顯示版本。

動作說明:[n1[,n2]]function
n1, n2 :不見得會存在,一般代表“選擇進行動作的行數”,舉例來說,如果我的動作是需要在 10 到 20 行之間進行,則寫作“10,20動作行爲”。

function:
a :新增, a 的後面可以接字串,而這些字串會在新的一行出現(目前的下一行)~
c :取代, c 的後面可以接字串,這些字串可以取代 n1,n2 之間的行!
d :刪除,因爲是刪除啊,所以 d 後面通常不接任何內容;
i :插入, i 的後面可以接字串,而這些字串會在新的一行出現(目前的上一行);
p :列印,亦即將某個選擇的數據印出。通常 p 會與參數 sed -n 一起運行~
s :替換,通常這個s的動作可以搭配正規表示法!例如 1,20s/old/new/g。

4. 典型示例

4.1 刪除行操作

(1)將 /etc/passwd 的內容列出並且列印行號,同時,請將第 2~5 行刪除。

[b3335@MIC ~]$ nl -n ln /etc/passwd | sed '2,5d'
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
.....(後面省略).....

注意:原本應該是要下達 sed -e 纔對,當只有一個動作的時候,沒有 -e 也行,但是多於一個動作時必須要使用 - e 選項來指定動作。

同時也要注意的是, sed 後面接的動作,請務必以兩個單引號括住。

(2)只要刪除第 2 行。

nl /etc/passwd | sed '2d'

(3)要刪除第 3 到最後一行

nl /etc/passwd | sed '3,$d'

4.2 新增行操作

(1)在第二行後加上 "I like drinking tea"。

[b3335@MIC ~]$ nl -n ln /etc/passwd | sed '2a I like drinking tea'
1  root:x:0:0:root:/root:/bin/bash
2  bin:x:1:1:bin:/bin:/sbin/nologin
I like drinking tea
3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(後面省略).....

(2)那如果是要在第二行前加入。

nl /etc/passwd | sed '2i drink tea'
//或
nl /etc/passwd | sed '1a drink tea'

(3)在第二行後面加入兩行,“I like drinking tea"與"I like drinking beer”。

[b3335@MIC ~]$ nl -n ln /etc/passwd | sed '2a I like drinking tea\nI like drinking beer'
1       root:x:0:0:root:/root:/bin/bash
2       bin:x:1:1:bin:/bin:/sbin/nologin
I like drinking tea
I like drinking beer
3       daemon:x:2:2:daemon:/sbin:/sbin/nologin
…(後面省略)…

或者每一行使用反斜槓、來分開,就可以在命令行中將一條命令分開多行輸入,如下:

[b3335@MIC ~]$ nl -n ln /etc/passwd | sed '2a I like drinking tea\
> I like drinking beer'

4.3 替換行操作

將第 2-5 行的內容替換成爲 "No 2-5 number"。

[b3335@MIC ~]$ nl -nln /etc/passwd | sed '2,5c No 2-5 number'
1       root:x:0:0:root:/root:/bin/bash
No 2-5 number
6       sync:x:5:0:sync:/sbin:/bin/sync
.....(後面省略).....

4.4 選擇行打印

僅列出 /etc/passwd 文件內的第 5-7 行。

[root@www ~]# nl -nln /etc/passwd | sed -n '5,7p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

4.5 數據的查找並進行相關操作

(1)數據的查找並顯示

搜索 /etc/passwd 有 root 關鍵字的行並輸出。

[b3335@MIC ~]$ nl /etc/passwd | sed -n '/root/p'
1  root:x:0:0:root:/root:/bin/bash11
operator:x:11:0:operator:/root:/sbin/nologin

(2)數據的查找並刪除

刪除 / etc/passwd 所有包含 root 的行,其他行輸出。

[b3335@MIC ~]$ nl /etc/passwd | sed '/root/d'
2 daemon:x:1:1:daemon:/usr/sbin:/bin/sh
3 bin:x:2:2:bin:/bin:/bin/sh…(下面忽略)…

如果想刪除匹配的字符串,使用如下命令:

[b3335@MIC ~]$ nl /etc/passwd | sed 's/root//g'

(3)數據的查找並替換

除了整行的處理模式之外, sed 還可以用行爲單位進行部分數據的搜尋並取代。基本上 sed 的搜尋與替代的與 vi 相當的類似!他有點像這樣:

sed 's/被取代的字串/新的字串/g

(4)數據的搜尋並執行命令

搜索 / etc/passwd, 找到 root 對應的行,執行後面花括號中的一組命令,每個命令之間用分號分隔,這裏把 bash 替換爲 blueshell,再輸出這行:

nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p}'
1 root:x:0:0:root:/root:/bin/blueshell

如果只替換 / etc/passwd 的第一個 bash 關鍵字爲 blueshell,就退出

nl /etc/passwd | sed -n '/bash/{s/bash/blueshell/;p;q}' 
1 root:x:0:0:root:/root:/bin/blueshell

4.6 多點編輯

一條 sed 命令,刪除 / etc/passwd 第三行到末尾的數據,並把 bash 替換爲 blueshell

nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1  root:x:0:0:root:/root:/bin/blueshell
2  daemon:x:1:1:daemon:/usr/sbin:/bin/sh

-e 表示多點編輯,第一個編輯命令刪除 / etc/passwd 第三行到末尾的數據,第二條命令搜索 bash 替換爲 blueshell。

4.7 直接修改文件

sed 可以直接修改文件的內容,不必使用管道命令或數據流重導向!不過,由於這個動作會直接修改到原始的文件,所以請你千萬不要隨便拿系統配置來測試,使用時也要慎重。我們使用下載的 regular_express.txt 文件來測試看看吧!

利用 sed 將 regular_express.txt 內每一行結尾若爲 . 則換成 !

[root@www ~]# sed -i 's/\.$/!/g' regular_express.txt

利用 sed 直接在 regular_express.txt 最後一行加入 "# This is a test"。

[root@www ~]# sed -i '$a # This is a test' regular_express.tx

由於 $ 代表的是最後一行,而 a 的動作是新增,因此該文件最後新增 "# This is a test"。

sed 的 - i 選項可以直接修改文件內容,這功能非常有幫助!

舉例來說,如果你有一個 100 萬行的文件,你要在第 100 行加某些文字,此時使用 vim 可能會瘋掉!因爲文件太大了!那怎辦?就利用 sed 啊!透過 sed 直接修改 / 取代的功能,你甚至不需要使用 vim 去修訂!

轉自:戀貓大鯉魚 dablelv.blog.csdn.net/article/details/53197905

****推薦關注「算法愛好者」,修煉編程內功

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/jUEmmpBb3PgtXl5H31QjOg