安卓系统

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

C$50 Finance

C$50 Finance

目录:

Anonim

在处理文本文件时,经常需要在一个或多个文件中查找并替换文本字符串。

sed 是一个处理者。 它可以对文件和输入流(例如管道)执行基本的文本操作。 使用 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

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

您可能已经注意到,在前面的示例中, foobar 字符串中的子字符串 foo 也被替换了。 如果这不是想要的行为,请在搜索字符串的两端使用单词边界表达式( \b )。 这样可以确保部分单词不匹配。

sed -i 's/\bfoo\b/linux/g' file.txt

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

要使模式匹配不区分大小写,请使用 I 标志。 在下面的示例中,我们同时使用了 g I 标志:

sed -i 's/foo/linux/gI' file.txt

123 linux linux linux linux /bin/bash Ubuntu linuxbar 456

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\{3}\b/number/g' file.txt

number Foo foo foo foo /bin/bash demo foobar number

sed的另一个有用功能是您可以使用 & 匹配的模式相对应的&字符 & 。 该字符可以多次使用。

例如,如果要在每个3位数字周围添加大括号 {} ,请键入:

sed -i 's/\b\{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

file.txt file.txt.bak

递归查找和替换

有时您想递归地在目录中搜索包含字符串的文件,并替换所有文件中的字符串。 这可以通过使用诸如 find grep 命令以递归方式在目录中查找文件并将文件名传递给 sed

以下命令将在当前工作目录中递归搜索文件,并将文件名传递给 sed

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

为了避免名称中包含空格的文件出现问题,请使用 -print0 选项,该命令告诉 find 打印文件名,后跟一个空字符,然后使用 xargs -0 将输出通过管道传递给 sed

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终端