如何使用sed查找和替換文件中的字符串

使用文本文件時,通常需要查找並替換一個或多個文件中的文本字符串。

sed 是一個 s治療 監視器它可以對文件和輸入流(例如管道)執行基本的文本操作。 用 sed,您可以搜索,查找和替換,插入和刪除單詞和行。 它支持基本和擴展的正則表達式,使您可以匹配複雜的模式。

在本文中,我們將討論如何查找和替換字符串 sed。 我們還將向您展示如何執行遞歸搜索和替換。

查找並替換為字符串 sed

有幾種版本 sed,它們之間在功能上有所不同。 macOS使用BSD版本,而大多數Linux發行版均隨附GNU sed 默認情況下預先安裝。 我們將使用GNU版本。

使用以下內容搜索和替換文本的一般形式 sed 採用以下形式:

sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
  • -i – 默認, sed 將其輸出寫入標準輸出。 這個選項告訴 sed 在適當位置編輯文件。 如果提供了擴展名(例如-i.bak),則會創建原始文件的備份。
  • s -替代命令,可能是sed中最常用的命令。
  • / / / -分隔符。 它可以是任何字符,但通常是斜杠(/)字符。
  • SEARCH_REGEX -要搜索的普通字符串或正則表達式。
  • REPLACEMENT -替換字符串。
  • g -全局替換標誌。 默認, sed 逐行讀取文件,僅更改第一次出現的 SEARCH_REGEX 在一條線上。 提供替換標誌後,所有出現的事件都將被替換。
  • INPUTFILE -您要在其上運行命令的文件的名稱。

良好的做法是在引號周圍加上引號,以使Shell元字符不會擴展。

讓我們看看如何使用 sed 命令使用其一些最常用的選項和標誌來搜索和替換文件中的文本。

出於演示目的,我們將使用以下文件:

file.txt

123 Foo foo foo 
foo /bin/bash Ubuntu foobar 456

如果 g 省略標誌,僅替換每行中搜索字符串的第一個實例:

sed -i 's/foo/linux/' file.txt
123 Foo linux foo 
linux /bin/bash Ubuntu foobar 456

帶有全局替換標誌 sed 替換所有出現的搜索模式:

sed -i 's/foo/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456

您可能已經注意到,子字符串 foo 在 – 的裡面 foobar 在前面的示例中字符串也被替換。 如果這不是想要的行為,請使用單詞邊界表達式(b)放在搜索字符串的兩端。 這樣可以確保部分單詞不匹配。

sed -i 's/bfoob/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu foobar 456

要使模式匹配不區分大小寫,請使用 I 旗。 在下面的示例中,我們同時使用了 gI 標誌:

sed -i 's/foo/linux/gI' file.txt
123 linux linux linux 
linux /bin/bash Ubuntu linuxbar 456

如果要查找並替換包含定界符(/),則需要使用反斜杠()以逃脫斜線。 例如替換 /bin/bash/usr/bin/zsh 你會用

sed -i 's//bin/bash//usr/bin/zsh/g' file.txt

更簡單易讀的選項是使用另一個定界符。 大多數人使用豎線(|)或冒號(:),但您可以使用其他任何字符:

sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo 
foo /usr/bin/zsh Ubuntu foobar 456

您也可以使用正則表達式。 例如,要搜索所有3位數字並將其替換為字符串 number 您將使用:

sed -i 's/b[0-9]{3}b/number/g' file.txt
number Foo foo foo 
foo /bin/bash demo foobar number

sed的另一個有用功能是您可以使用&字符 & 對應於匹配的模式。 該字符可以多次使用。

例如,如果要添加花括號 {} 在每個3位數附近輸入:

sed -i 's/b[0-9]{3}b/{&}/g' file.txt
{123} Foo foo foo 
foo /bin/bash demo foobar {456}

最後但並非最不重要的一點是,使用以下命令編輯文件時備份總是一個好主意 sed。 為此,只需提供備份文件的擴展名即可 -i 選項。 例如,編輯 file.txt 並將原始文件另存為 file.txt.bak 您將使用:

sed -i.bak 's/foo/linux/g' file.txt

要確保已創建備份,請列出帶有 ls 命令:

ls
file.txt file.txt.bak

遞歸查找和替換

有時,您可能需要遞歸地在目錄中搜索包含字符串的文件,然後在所有文件中替換該字符串。 這可以使用以下命令來完成 find 要麼 grep 在目錄中遞歸查找文件並將文件名傳遞到 sed

以下命令將遞歸搜索當前工作目錄中的文件,並將文件名傳遞給 sed

find . -type f -exec sed -i 's/foo/bar/g' {} +

為避免名稱中包含空格的文件出現問題,請使用 -print0 選項,說明 find 打印文件名,後跟一個空字符並將輸出通過管道傳遞到 sed 使用 xargs -0

find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

要排除目錄,請使用 -not -path 選項。 例如,如果您要替換本地git repo中的字符串,以排除所有以點(.), 使用:

find . -type f -not -path '*/.*' -print0 | xargs -0 sed -i 's/foo/bar/g'

如果要僅搜索和替換具有特定擴展名的文件上的文本,請使用:

find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'

另一種選擇是使用 grep 命令以遞歸方式查找包含搜索模式的所有文件,然後將文件名傳遞給 sed

grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'

結論#

儘管看似複雜,但起初是使用以下命令搜索和替換文件中的文本 sed 很簡單

要了解更多有關 sed 命令,選項和標誌,請訪問GNU sed手冊和Grymoire sed教程。

如果您有任何疑問或反饋,請隨時發表評論。

sed終端

Sidebar