返回部落格

Linux 中用於處理文字的 Sed 串流編輯器概述

Linux 中用於處理文字的 Sed 串流編輯器概述

命令 sed 是 stream editor(串流編輯器)的縮寫。它是 Linux/UNIX 系統上廣受歡迎的工具。Sed 本身並不是文字編輯器。然而,它可以進行各種修改以操作指定的文字。文字輸入是以串流的形式傳送。Sed 接著對該串流執行指定的動作。本指南 概述了 sed 命令以及如何操作它,以便在 Linux 中成功操作文字。

Linux 中的 Sed

的輸入串流 sed 可以來自文字檔案或 STDIN(標準輸入)。我們可以處理另一個命令的輸出,或者直接處理文字檔案。sed 工具已預裝在所有 Linux 發行版中。

Sed 使用概述

The sed 命令遵循以下結構:

為了演示目的,我們獲取了文字版本的 GPL 授權條款第 3 版:

Manipulate Text with Sed 7

以下 sed 命令將列印該文字檔案的內容:

在這裡,sed 正在執行單引號內描述的操作並列印輸出。由於未定義任何選項,sed 將僅執行空白操作並列印檔案的完整內容。

Sed 也接受來自其他命令的輸出作為輸入串流。在下一個範例中,將 GPL v3 文字檔案的內容透過管線傳送至 sed 以執行空白操作:

如何列印行

在未指定任何選項的情況下,sed 將直接列印檔案的所有內容。相反地,我們可以明確傳送列印命令,將結果直接列印到標準輸出 (STDOUT)。

要列印輸出,請使用字元 p:

Manipulate Text with Sed 6

預設情況下,sed 會將輸出列印到螢幕上。因為我們特別使用了列印命令,sed 將會把每一行列印兩次。Sed 是逐行運作的。它讀取一行、執行特定操作、將其列印出來,然後移至下一行。

如我們所見,每一行都被列印了兩次。如果這樣的結果令人困惑,我們可以使用 -n 選項來清理它。它會抑制自動列印功能。因為我們正在傳送列印命令,所以不需要啟用預設的輸出列印功能:

Regex 字元類別

在正規表示式中,有各種字元類別。這些類別中的每一個都有一個範圍。許多類別也有多個運算式。大多數類別是字元範圍:

    • [a-z]:小寫字元
    • [A-Z]:大寫字元
    • [0-9]:數字
    • [a-zA-z]:英文字母
    • [a-zA-z0-9]:任何英數字元

這些字元類別也有不同的標記法:

    • [:lower:]:小寫字元
    • [:upper:]:大寫字元
    • [:digit:]:數字
    • [:alpha:]:英文字母
    • [:alphanum:]:英數字元

例如,以下命令將列印包含至少一個數字的所有行:

Manipulate Text with Sed 3

位址範圍

我們可以指定要處理的文字串流的特定部分。它可以是某一行的靜態位置,也可以是某個行範圍。在第一個範例中,我們將列印 GPL v3 文字檔案的第 5 行:

$ sed -n

除了單行之外,我們還可以指定要處理的行範圍。在這裡,我們指定了從第 5 行到第 9 行(共 5 行)的位址範圍,供 sed 進行處理:

gpl-3.0.txt

指定行位址也有不同的方法。除了由我們自己確定行號之外,我們還可以重新調整前一個範例,以便 sed 將從第 5 行開始,並對接下來的 5 行進行操作:

5,+5p

另一種指定行的方法是使用間隔。在下一個範例中,sed 將從第 1 行開始,並對每隔一行進行操作:

刪除文字

到目前為止,我們已經介紹了如何列印目標文字行。除了列印之外,我們還可以從輸出中刪除這些行。在接下來的範例中,我們將從開頭刪除多行。在這裡,我們不需要使用選項 -n,因為我們希望 sed 列印其他所有未被刪除的內容。對於刪除行,我們將使用選項 d:

Manipulate Text with Sed 2

請注意,來源檔案仍然完好無損。Sed 只是在輸出過程中執行行刪除。如果您願意,可以將 sed 輸出儲存到檔案中。您可以覆寫原始檔案或將其另存為其他檔案:

除了手動將輸出寫入檔案之外,sed 還可以對原始檔案進行就地編輯(in-place edit)。簡而言之,sed 將編輯原始檔案並寫入所做的任何變更。此方法會覆寫原始檔案,因此應謹慎使用:

因為就地編輯很危險,sed 提供了備份功能。在進行就地編輯時,請使用 -i.bak 代替 -i,以便在編輯前進行備份。Sed 將建立帶有 .bak 副檔名的備份檔案:

文字替換

到目前為止,這是 sed 最常見的應用之一。它會搜尋文字模式,並用指定的文字替換該模式。在這裡,文字模式是用正規表示式(簡稱 regex)來描述的。要了解更多關於使用正規表示式的資訊,請參考這篇概述如何結合使用 Grep 與正規表示式來搜尋文字模式 的教學。

以下是使用正規表示式進行最基本文字替換的範例:

在這裡,s 是用於替換的命令。斜線是模式和替換內容的分隔符號。讓我們來實際操作一下:

Manipulate Text with Sed 5

下一個範例將示範底線(_)的用法。在這裡,底線將作為分隔符號:

在這裡,我們正在搜尋 com/index 並將其變更為 net/home。 請注意底線的位置,因為它們非常關鍵。例如,如果您漏掉了最後一個底線,sed 將會拋出錯誤:

我們需要一個虛擬檔案來練習一些替換。在這裡,我有一個裁剪版的 GPL v3 文字檔:

讓我們來進行一些基本的文字替換:

看看下一個範例。我們想要將所有出現的 the 變更為 THE :

$ echo

注意到什麼了嗎?Sed 並沒有變更所有出現的 the。 事實上,它只變更了第一個。這是怎麼回事?這是選項 s 的預設行為。它僅匹配指定行的第一個出現位置,然後移至下一行。為了確保 sed 會檢查整行以尋找搜尋模式,我們需要使用一個選用旗標 g。讓我們修正這個命令:

現在它已如預期般運作。另一種有趣的使用命令方式是指定要變更的出現次數。在前面的範例中,有 3 個 the,對吧?如果我們指定只變更第 3 出現位置?變更將發生在選用旗標處:

如果您正在處理大型文字檔案,那麼如果 sed 僅列印發生替換的那些行,這將會很有幫助。為了實現這一點,我們需要添加另一個額外的旗標 p:

Manipulate Text with Sed 4

區分大小寫

預設情況下,所有的 sed 操作都是區分大小寫的。以下命令將演示區分大小寫的預設行為:

$ echo "HELLO WORLD"

由於大小寫不匹配,因此沒有任何變化。在這種情況下,我們可以告訴 sed 停用區分大小寫。為此,請添加選用旗標 i:

如何替換和引用文字

要說到 sed 的強大之處,主要在於它使用正規表示式的能力。透過更進階且複雜的 regex 模式,我們可以完成更多工作。例如,我們可以替換從檔案開頭到特定位置的文字。請看以下運算式:

在這裡,插入符號文字 (^) 表示行首。比對任何字元的運算子是用句點表示 (.). 星號 (*) 是萬用字元運算式,比對從行首一直到 GNU.

另一個有趣的技巧是使用 & 符號。我們可以用它來突顯 sed 找到搜尋模式的區域:

Manipulate Text with Sed

結語

在本教學中,我們探索了 sed 命令的基本用法。我們學習了如何列印特定行、搜尋文字、刪除和替換文字、覆寫文字以及使用正規表示式。一個建構得當的 sed 命令可以顯著地改變文字文件。現在,在 sed.

的幫助下,您已可以成功地在 Linux 中操作文字。祝您使用愉快!

author

Hark Labs

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的創意設計師,專注於透過傳統與創新行銷渠道建立一致的企業形象。他擅長將藝術願景與策略行銷相融合,創造具有影響力的品牌敘事。

留言

目前尚無留言。成為第一個留言的人吧。