天天看點

sed

        sed以非互動式的方法執行操作,根據使用者預先設定的規則來操作指定的文本流。該文本流通常是前面某個操作的輸出,這個操作可能是由使用者執行也可能是一組自動運作的指令的一部分;另外,sed能夠操作檔案,如果使用者具有一組内容相似的檔案,并且需要對所有這些檔案的内容執行特定的編輯,那麼sed指令能夠讓使用者輕易地實作這一點。例如以下指令:假設兩個檔案name1.txt和name2.txt将其合并成一個檔案并将paul替換成pablo。

% vi name1.txt

paul

craig

debra

joe

jeremy

% vi name2.txt

katie

mike

tom

pat

% sed -e s/paul/pablo/g names1.ext name2.txt > name3.txt

%cat name3.txt

pablo

bablo

%

指令把兩個檔案合并在一起,同時對兩個檔案中的名字"paul" 執行替換。

工作原理

        sed讀取指定的檔案和/或标準輸入,并按照一組指令的訓示來修改輸入,然後将輸入寫到标準輸出中,如果需要的話,也可以進行重定向。

        注意sed輸出将按照處理的先後次序顯示兩個件的所有行。原始檔案并沒有改變;隻有輸出結果,或者就上面的指令而言,由輸出建立的檔案中才包含了pablo對paul的替換。

-e選項

        将多個編輯指令作為指令行參數時就需要用到-e選項。例如:

% sed -e 's/paul/pablo/; s/pat/patricia/' name1.txt name2.txt

        注意,雖然并沒有要求将指令放入單引号内(第一個sed示例就沒有使用單引号),但最好這樣做。将指令放入單引号有助于使用者區分與編輯有關的參數以及與其他資訊,例如需要編輯的檔案有關參數。此外,單引号将防止shell解釋在編輯指令中找到的特殊字元或空格。

        有三種方法可以為sed提供一連串的編輯指令,以便在指令進行處理。一種方法是使用分号将編輯指定隔開,如上例。

        第二種方法是在每個編輯參數前加一個-e,如下例:

    % sed -e 's/paul/pablo/g' -e 's/pat/patricia/g' name1.txt name2.txt

        第三種方法是,如果shell的多行記錄項功能可用,則使用該功能。下面的例子是在bash shell環境而不是在c shell中的用法:

    % sed '

    > s/paul/pablo/

    > s/pat/patricia/ name1.txt name2.txt '

sed檔案

        當然,無論使用上述的哪種方法,在指令上為sed輸入一長串的編輯指令都是不實用的,sed能夠讀取純指令檔案以擷取一連串的指令,該檔案含有類似于指令行參數的編輯指令,利用-f選項可以實作這一點。

        -f 參數訓示的檔案簡單地指定一個文本檔案,該檔案含有一連串順次執行的操作。這些操作大部分都可以在vi中手動完成:替換文本、删除行、删除新文本等。這種做法的優勢在于所有的編輯指令都放在一個地方,可以一次執行所有指令。

示例:

使用vi建立以下指令檔案edits.sedscr

% vi edit.sedscr

s/pat/patricia/

s/tom/thomas

s/joe/joseph/

ld

調用sed

% sed -f edits.sedscr name1.txt name2.txt >name3.txe

注意,sed将按照文中列出指令先後次序,依次執行每個指令,同樣,原始檔案沒有改變;隻有輸出中包含sed執行腳本檔案時所産生的結果。本例将輸出重定向到檔案中,在大多數情況下,除非将sed的輸出重定向到另一個程式,否則這是處理sed輸出的首選方法----将其存放到檔案中。

sed 指令

        sed編輯器含有25個指令,下面列出了一些最有用的指令。

xa\text     追加

将指令後的文本追加到比對特定行位址(x)的每一行中。用希望追加text的行号(位址)來替換x

xd           删除

删除指定行号的一行或多行。也就是說,這些行不會發送到标準輸出中。

xq           退出

遇到指定的位址就退出。

xr file      讀取檔案

讀取檔案的内容并在指定的行位址之後追加文本

xs/pattern/replacement text/flags 置換

将每個指定行上的pattern替換成replacement。

[reg ex pattern]w file    寫檔案

将模式空間的内容追加到檔案中。

        雖然這些典型的指令在編輯檔案時将行位址作為參數,但是行位址是可選的,要取代行位址,可以使用一些模式,這些模式包括兩條斜線之間的正規表達式、行号或者行取址符号。例如前面示例中使用的替代指令列出了模式而不是行位址進行比對:

        如果使用行位址,大多數sed指令能夠同時處理一行或多行,要處理多行,需要用逗号訓示行範圍的行位址隔開。示例

#删除第一和第二行

1,2d

#删除行2到5

2,5d

#追加文本到第一行和第二行

1,2a\ hello world!

#讀取已給的檔案内容,并追加到第二行的後面。

2r append_file.txt

        但是,有些指令隻接受單行,例如quit。這是有實際意義的,因為不能将該sed腳本應用于一個範圍内的行----sed隻能退出一次。

#在第100行退出

100q

可以将在相同的位址上執行的多個指令組合在一起并用花括号括起來:

#删除最後一行并退出

${d

   q

}

注意,第一個指令可以與開始的括号放在同一行上,但是結束的括号必須單獨放在一行上。另外,還要注意括号内指令的縮進。如果不知道檔案中最後一行的位址,可以使用美元符号$來指定,為了代碼的可讀性不提倡多個指令放在同一行上,因為即使每個指令自行一行,閱讀sed腳本也是相當困難的。