简介
文本处理中一个常见的任务是「查找和替换」。在文字处理器中,这通常通过交互方式完成;在 Linux 命令行环境中,sed 以可编写脚本、无需交互的方式实现相同的功能。
sed 是一个非交互式文本编辑器,会逐行处理文本。它特别适合执行替换任务,例如将指定模式替换为新文本。在自动化场景中,这非常有用,因为不需要人工反复打开编辑器执行相同的修改。
在本实验中,你将学习:
- 替换文本(
s):执行基本的查找和替换操作。 - 全局替换(
g):替换一行中某个模式的所有匹配项,而不只是第一个匹配项。 - 使用自定义分隔符:使用其他分隔符处理包含斜杠的文本,例如文件路径。
- 创建备份并原地编辑:自动创建备份副本,从而更安全地修改文件。
基本替换
先对字符串执行一个简单的替换,将单词「World」改为「Linux」。
sed 中用于替换的命令是 s。
语法为 s/Pattern/Replacement/。
这种命令形式非常常见,因此许多用户会把 sed 视为「查找和替换工具」。但实际上,sed 是一个流编辑器,而替换只是它最常用的编辑命令之一。
运行以下命令查看效果:
echo "Hello World" | sed 's/World/Linux/'
工作原理:
echo将「Hello World」发送到标准输出。- 管道
|将该输出传递给sed。 sed读取文本,查找模式「World」,将其替换为「Linux」,然后打印结果。
注意:此命令不会永久修改原始数据;它只会将修改后的文本输出到屏幕(标准输出)。
理解这一点对于安全地进行命令行编辑非常重要。在 Unix 风格的操作中,工具通常会先显示转换后的数据流,之后再由你决定是否保存或重定向结果。
全局替换
默认情况下,sed 只会替换每一行中找到的第一个匹配项。
如果文本是「apple apple」,将「apple」替换为「orange」后,sed 会输出「orange apple」。
要替换一行中的所有匹配项,必须在替换命令末尾使用全局标志(g)。
需要特别注意的是「每一行」。sed 一次处理一行,因此 g 标志会影响当前行中的所有匹配项,而不是把整个文件作为一个巨大的文本块进行处理。
先查看示例文件 quote.txt:
cat quote.txt
输出:I love Coding. Coding is fun.
现在不使用全局标志,将「Coding」替换为「Programming」:
sed 's/Coding/Programming/' quote.txt
结果:I love Programming. Coding is fun.
注意,第二个「Coding」没有被替换。
现在添加 g 标志:
sed 's/Coding/Programming/g' quote.txt
结果:I love Programming. Programming is fun.
现在两个匹配项都已成功替换。
使用不同的分隔符
标准的 sed 语法使用正斜杠 / 作为分隔符:s/old/new/。
但是,如果要替换的文本包含斜杠,例如文件路径 /usr/local/bin,就必须使用反斜杠转义每个斜杠。这样会使命令难以阅读:s/\/usr\/local\/bin/\/bin/。
幸运的是,sed 允许使用几乎任何字符作为分隔符。常见的替代分隔符包括 #、: 和 |。
选择易读的分隔符是一项实用技能,而不仅仅是语法技巧。当模式中包含许多 / 字符时,更换分隔符可以让命令更容易理解,也能减少出错的可能。
创建一个包含路径的文件:
echo "/usr/local/bin" > path.txt
现在使用 # 作为分隔符,将 /usr/local/bin 替换为 /bin:
sed 's#/usr/local/bin#/bin#' path.txt
结果:/bin
由于使用了 # 作为分隔符,sed 会将路径中的 / 字符视为普通文本,因此命令更加简洁、易读。
创建备份并原地编辑
到目前为止,sed 只会将修改结果打印到屏幕。要直接修改文件(即「原地」修改),请使用 -i 选项。
但是,直接修改文件存在风险。如果模式写错,可能会丢失数据。更理想的做法是在修改文件前创建原始文件的备份。
为此,可以向 -i 选项提供扩展名,例如 -i.bak。
修改 quote.txt,并自动创建名为 quote.txt.bak 的备份:
sed -i.bak 's/fun/awesome/' quote.txt
现在查看修改后文件的内容:
cat quote.txt
结果:I love Coding. Coding is awesome.
然后确认备份文件存在,并检查其中是否保留了原始文本:
ls -l quote.txt.bak
cat quote.txt.bak
结果:I love Coding. Coding is fun.
对多个文件执行批量编辑时,建议采用这种做法。
这是因为非交互式编辑速度很快,但出错后不会主动提醒。当你自动化替换多个文件中的文本时,一个小小的模式错误可能会迅速扩散,因此保留原始副本是一种简单有效的安全措施。
总结
在本实验中,你学习了使用 sed 替换文本的基础知识:
- 替换(
s///):用于查找和替换文本的标准命令。 - 全局标志(
g):替换一行中某个模式的所有匹配项。 - 自定义分隔符:使用
#等字符安全处理包含/的路径和 URL。 - 原地编辑并创建备份(
-i.bak):在保留原始内容的同时安全地修改文件。
掌握这些技能后,你就能更高效、更安全地自动化复杂的文本处理任务。



