天天看點

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

一、SED介紹

SED(Stream EDitor)是一個文本解析轉換工具。它遵循簡單的工作流:讀取、執行、顯示。

  • 讀取:SED從輸入流(檔案,管道或者标準輸入)中讀取一行并且存儲到模式空間(pattern buffer)的内部緩沖區
  • 執行:預設情況下,所有的SED指令都在模式空間中順序執行;而且SED指令将會在所有的行上依次執行,除非指定了行的位址
  • 顯示:發送修改後的内容到輸出流。在發送資料之後,模式空間将會被清空

注意

  • 模式空間是一塊緩沖區,在sed編輯器執行指令時會儲存待檢查的文本
  • 預設情況下,所有的sed指令都是在模式空間中執行,是以輸入檔案并不會發生改變
  • 還有另外一個緩沖區叫做保持空間(hold buffer),在處理模式空間中的某些行時,可以用保持空間來臨時儲存一些行。在每一個循環結束的時候,sed會移除模式空間中的内容,但是該緩沖區中的内容在所有的循環過程中是持久存儲的。

示例

首先檢視quote.txt檔案内容:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

執行

sed '' quote.txt

結果如下:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

處理流程:sed指令先将文本中的一行内容存儲到它的模式空間中,然後在緩沖區執行指令;此處沒有提供sed指令,是以對該緩沖區沒有要執行的操作;最後删除模式空間的内容,并列印該内容到标準輸出。最後流程總結如下:

一行内容->模式空間->執行指令->删除模式空間内容->列印

二、使用

2.1 基礎文法

sed -option 'command' file

2.1.1 指令說明

command 說明
d 删除 (delete)
s 單個字元替換 (substitute)
p 列印 (print)
w 寫入 (write)指令
a 追加 (append)
c 行替換 (change)
i 插入 (insert)
l 顯示隐藏字元
q 退出指令 (quit)
r 檔案讀取 (read)
e 執行外部指令
! 排除指令
  • d

    books.txt内容如下:

    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
    執行

    sed '2d' books.txt

    指令,删除第二行内容:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • s

    執行

    sed 's/$/!/'

    指令,給books.txt檔案每一行結尾加上感歎号:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • p

    首先看

    sed 'p' quote.txt

    指令執行結果:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

    sed '' quote.txt

    指令相比,每一行列印了兩次,這是因為在内容讀取進模式空間進行處理的時候,執行的指令是

    p

    ,列印内容(第一次),在處理完畢之後,模式空間的内容又列印到标準輸出(第二次)。

可以使用

-n

參數來抑制第二次的列印行為,

sed -n 'p' quote.txt

執行結果如下,同

sed '' quote.txt

指令結果相同:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • w

    文法

[address] w file
file是要寫入的檔案名,如果檔案名不存在,則會自動建立,如果已經存在,則會覆寫原内容
           

觀察以下兩條示例:

sed -n 'w books.bak' books.txt

,由于沒有指定位址,那麼會将檔案books.txt的所有内容都寫入到新檔案中。

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

sed -n '2,3 w junk.txt' books.txt

,将2到3行内容寫到新檔案中

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • a

    sed '$a 7) my append txt' books.txt

    ,給最後一行追加内容
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • c

    當提供行的位址範圍時,所有行都被作為一組替換成單行文本

sed '2,3c they are changed' books.txt

指令,替換2,3行内容:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • i

    sed '1i insert txt' books.txt

    ,給第一行插入内容,插入到前一行:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • l

    sed 's/ /\t/g' books.txt > junk.txt

    ,首先将books.txt中的空格替換成/t

    sed -n 'l' junk.txt

    ,檢視junk.txt檔案的隐藏字元
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
    此外,

    l

    指令還能讓文本按照指定的寬度換行:

    sed -n 'l 40' books.txt

    ,文本中的每一行如果超過40字元,則換行:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • q

    文法

[address]q [value]
隻支援單個位址比對
value作為程式的傳回,可以寫也可不寫
           

sed '3q 6' books.txt

,比對第三行退出,傳回值6:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • r

    r

    指令可以從外部檔案中讀取内容,并在滿足條件的時候顯示
[address]r file
           

sed '3r junk.txt' books.txt

,将junk.txt檔案内容在第三行之後顯示:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • e

    sed '3e date' books.txt

    ,執行外部指令date:
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • !

    使原來起作用的指令不起作用

    sed '/Paulo/!p' books.txt

    :
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.1.2 參數說明

option 說明
-n 抑制輸出
-e 執行多條指令
-f 執行指定腳本檔案裡的指令
  • -n

    預設情況下,模式空間的内容在處理完畢之後将會列印到标準輸出,該選項用于阻止該行為。

可以檢視

sed '' quote.txt

指令加-n參數和不加參數的情況如下

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • -e

使用-e選項,執行多次删除指令,

sed -e '2d;5d' books.txt

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • -f

腳本檔案内容如下,即删除第二行和第五行内容:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

執行

sed -f testCommand books.txt

指令,結果中删除了第二行和第五行内容,說明指令生效:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.2 循環和分支

sed提供用于控制執行流的循環和分支語句

2.2.1 循環

sed可以根據标簽(label)跳轉到某一行繼續執行;我們可以定義如下标簽:

:label
:start
:end
:up
           

定義完标簽之後,如果要跳轉到指定的标簽,使用b指令後跟着标簽名;如果忽略标簽名,sed将會跳轉到sed檔案的結尾。

b start    -->表示跳轉到start标簽的位置
           
  • 示例

    首先檢視示例檔案books2.txt的内容:

    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
    執行以下指令:
[email protected]:/opt/shell/sed-demo-master# sed -n '
> h;n;H;x
> s/\n/,/
> /Paulo/!b Print
> s/^/-/
> :Print
> p' books2.txt
           

結果:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

指令分析:

  • 第一行

    h;n;H;x

    指令,

    h

    是指将目前模式空間中的内容覆寫到保持空間中;

    n

    是用于提前讀取下一行,并覆寫目前模式空間中的這一行;

    H

    将目前模式空間的内容追加到保持空間;

    x

    用于交換模式空間和保持空間中的内容。最終達到的效果就是每次讀取兩行放到模式空間中進行處理。
  • 第二行

    s/\n/,/

    指令用于将上面的兩行内容進行處理,把換行符替換成逗号。
  • 第三行

    /Paulo/!b Print

    指令,進行比對,如果不滿足比對條件,則跳轉到Print标簽,否則執行第四行指令。
  • 第四行

    s/^/-/

    指令,将這一行的開頭添加

    -

  • 第五行

    :Print

    隻是一個标簽名
  • 第六行

    p

    ,列印指令;

不符合比對條件的執行流,過程為

2->3->5->6

;符合比對條件的執行流,

2->3->4->5->6

,兩者差別隻是是否少了第四行指令而已,也就是說,标簽後的内容,都是一樣要執行的。

以上的指令也可以寫在同一行:

sed -n 'h;n;H;x;s/\n/,/;/Paulo/!b Print;s/^/-/;:Print;s/^/!/;p' books2.txt
           
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.2.2 分支

使用t指令建立分支,隻有目前置條件成功的時候,t指令才會跳轉到該标簽。

前置條件:替換(s)指令執行成功
  • 示例

    執行指令

sed -n '
> h;n;H;x
> s/\n/,/
> :loop
> /Paulo/s/^/-/
> /----/!t loop
> p' books2.txt

           

結果:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

指令分析(前兩行與以上示例一緻):

  • 第三行

    :loop

    ,定義了一個loop标簽
  • 第四行

    /Paulo/s/^/-/

    ,比對存在Paulo的行,如果存在則在開頭添加一個

    -

  • 第五行

    /----/!t loop

    (重點),檢查上面添加

    -

    之後,是否滿足有四個

    -

    ,如果不滿足,則跳到第三行,繼續往下執行,再向最前面添加一個

    -

    ;如果滿足,則向下執行

    p

    指令。

是以此示例的前置條件就是第四行指令中的

s

指令執行成功,才會繼續第五行指令。如果第四行指令沒有執行成功,則直接執行最後一行

p

指令。

2.3 行尋址

sed中包含有以下兩種形式的行尋址:

  1. 以數字形式表示的行區間
  2. 以文本模式來過濾行

以上兩中方式的文法都相同

[address]command
           

2.3.1 數字方式行尋址

  • 指定某一行,使用單獨的數字

    sed -n '3d' books.txt

    ,指定第三行執行

    d

    指令
  • 指定行的範圍,起始行和結束行之間用逗号隔開

    sed -n '2,5 p' books.txt

    ,第二行到第五行執行

    p

    指令
  • $代表檔案最後一行
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • M,+n

    ,標明第M行開始的下n行
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • M~n

    ,標明M行開始的每n行
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.3.2 文本模式過濾

  • /pattern/command

    ,使用/符号來開啟比對,同時以/符号結束
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.4 多行指令

sed編輯器執行基礎指令時,會基于換行符的位置将資料分成多行,一次處理一行的資料,然後移到下一行重複這個過程。

但是sed編輯器也有用來處理多行文本的特殊指令

指令 說明
N 将資料流中的下一行追加進來組成多行組一起處理
P 輸出多行文本的模式空間中的第一行

2.4.1 N - 加載下一行

sed 'N;s/\n/,/' books2.txt

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.4.2 P - 輸出第一行

sed -n 'N;P' books2.txt

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

2.5 特殊字元

sed中含有兩個可以用作指令的特殊字元:= 和**&**

2.5.1

=

指令

用于輸出行号

sed -n '$n' books2.txt

,輸出最後一行的行号:

shell三劍客之SED使用一、SED介紹二、使用三、正規表達式

三、正規表達式

3.1 定位符

字元 說明
^ 比對行的開頭
$ 比對行的結尾
  • ^

    sed '/^The/ p' books2.txt

    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • $
sed '/Coelho$/ p' books2.txt
           

3.2 特殊字元

字元 說明
. 比對除了換行符以外的所有單個字元
  • .
$ echo -e 'cat\ndog\nmat\nrats' | sed -n '/..t$/ p' 
cat
mat
           

3.3 字元集相關

符号 說明
[] 比對字元集
[^] 排除字元集
[-] 比對字元範圍
  • []
    shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
  • [^]

    [^cn]

    ,排除出現c或者n字元
  • [-]

    [a-c]

    ,指出現a到c任一字元

3.4 限定符

字元 說明
比對0次到1次
+ 比對一次到多次
* 比對0次到多次
{n} 精确比對n次
{n,} 至少比對n次
{n,m} 比對n-m次

3.5 元字元

字元 說明
\s 比對單個空白内容
\S 比對單個非空白内容
\w 比對單個單詞
\W 比對非單詞

繼續閱讀