我如何使用 Linux sed 命令来自动化文件编辑

这里有一些来自 Linux 命令行自动化文件编辑的技巧和窍门。
7 位读者喜欢这个。
computer screen

Opensource.com

当我使用 Linux 命令行时,无论我是在我的台式电脑上编写新程序还是在我的 Web 服务器上管理网站,我都经常需要处理文本文件。Linux 提供了强大的工具,我可以利用这些工具来完成我的工作。我经常使用 sed,这是一种可以根据模式修改文本的编辑器。

sed 代表流编辑器,它编辑文件中的文本并打印结果。使用 sed 的一种方法是识别文件中多次出现的字符串,并将它们替换为不同的字符串。您可以使用 sed 来处理文本文件,其程度似乎是无止境的,但我想分享一些我使用 sed 来帮助我管理文件的方法。

在 Linux 上搜索和替换文件中的文本

要使用 sed,您需要使用正则表达式。正则表达式是一组定义模式的特殊字符。我最常使用 sed 的例子是替换文件中的文本。替换文本的语法如下所示:s/原始文本/新文本/s 告诉 sed 执行文本替换或交换文本的出现。在斜杠之间提供原始文本和新文本。

此语法将仅替换每行中 原始文本 的第一次出现。要替换每次出现,即使原始文本在一行中出现多次,请在表达式末尾附加 g。这是一个例子:s/原始文本/新文本/g

要将此与 sed 一起使用,请使用 -e 选项指定此正则表达式

$ sed -e 's/originaltext/newtext/g'

例如,假设我有一个名为 game 的程序的 Makefile,它模拟 Conway 的生命游戏

.PHONY: all run clean

all: game

game: game.o
	$(CC) $(CFLAGS) -o game game.o $(LDFLAGS)

run: game
	./game

clean:
	$(RM) *~
	$(RM) *.o
	$(RM) game

名称 game 不是很有描述性,所以我可能会选择将其重命名为 life。将 game.c 源文件重命名为 life.c 很容易,但现在我需要修改 Makefile 以使用新名称。我可以使用 sed 将每次出现的 game 更改为 life

$ sed -e 's/game/life/g' Makefile
.PHONY: all run clean

all: life

life: life.o
	$(CC) $(CFLAGS) -o life life.o $(LDFLAGS)

run: life
	./life

clean:
	$(RM) *~
	$(RM) *.o
	$(RM) life

这会将 sed 输出打印到屏幕上,这是一个检查文本替换是否会执行您想要操作的好方法。要对 Makefile 进行这些更改,首先,备份文件,然后运行 sed 并将输出保存到原始文件名

$ cp Makefile Makefile.old
$ sed -e 's/game/life/g' Makefile.old > Makefile

如果您确信您的更改完全符合您的要求,请使用 -i--in-place 选项就地编辑文件。但是,我建议添加备份文件名后缀,如 --in-place=.old,以保存原始文件的副本,以防您以后需要恢复它。它看起来像这样

$ sed --in-place=.old -e 's/game/life/g' Makefile
$ ls Makefile*
Makefile  Makefile.old

在 Linux 上使用 sed 引用文件

您可以使用正则表达式的其他功能来匹配文本的特定实例。例如,您可能需要替换出现在行首的文本。使用 sed,您可以使用 ^,即插入符号字符,匹配行首。

我在替换文本中使用“行首”的一种方式是当我需要在电子邮件中引用文件时。假设我想在电子邮件中分享我的 Makefile,但我不希望将其作为文件附件包含在内。相反,我更喜欢在电子邮件正文中“引用”文件,在每行前面使用 >。我可以使用以下 sed 命令将编辑后的版本打印到我的终端,我可以将其复制并粘贴到新电子邮件中

$ sed -e 's/^/>/' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>	$(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>	./life
>
>clean:
>	$(RM) *~
>	$(RM) *.o
>	$(RM) life

s/^/>/ 正则表达式匹配每行的开头 (^) 并在那里放置一个 >。实际上,这使每行都以 > 符号开头。

制表符可能无法在电子邮件中正确显示,但我可以通过添加另一个正则表达式将 Makefile 中的所有制表符替换为几个空格

$ sed -e 's/^/>/' -e 's/\t/  /g' Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>  $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>  ./life
>
>clean:
>  $(RM) *~
>  $(RM) *.o
>  $(RM) life

\t 表示文字制表符,因此 s/\t/ /g 告诉 sed 将输入中的所有制表符替换为输出中的两个空格。

如果您需要对文件应用大量编辑,您可以将您的 -e 命令保存在文件中,并使用 -f 告诉 sed 使用该文件作为“脚本”。如果您需要经常进行相同的编辑,这种方法尤其有用。我可能已经使用名为 quotemail.sed 的脚本文件准备了用于在电子邮件中引用的 Makefile

$ cat quotemail.sed
s/^/>/
s/\t/  /g
$ sed -f quotemail.sed Makefile
>.PHONY: all run clean
>
>all: life
>
>life: life.o
>  $(CC) $(CFLAGS) -o life life.o $(LDFLAGS)
>
>run: life
>  ./life
>
>clean:
>  $(RM) *~
>  $(RM) *.o
>  $(RM) life

学习在 Linux 上使用 sed

sed 是您 Linux 命令行工具包中一个很棒的工具。浏览 sed 手册页,了解更多关于如何使用它的信息。在命令行键入 man sed 以获取关于不同命令行选项以及如何使用 sed 处理文本文件的完整文档。

接下来阅读什么
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发者,以 GNOME 中的可用性测试以及作为 FreeDOS 的创始人和项目协调员而闻名。

4 条评论

您可以做的另一件事来测试您是否要切换文本是运行 grep 来查找您认为要切换的文本。您将看到突出显示的所有文本实例。

很棒的文章,sed 是一个非常有用的工具!

最近我们将我们的 Moodle 实例移动到一个新盒子,并决定将网址更改为更合理的地址。在 cygwin 下使用 sed 编辑 MySQL 数据库转储非常轻松。事实上,这是唯一的方法。5.5MB 的转储无法在记事本、写字板等中打开。

对于 TAB 示例,您可以将所有 sed 操作放在一个参数中,而不是用复合分号“;”分隔它们,例如
sed -e 's/^/>/; s/\t/ /g' Makefile

另一个有用的方法是首先添加 REGEX,类似于 grepping,然后在行上应用运算符,例如
sed '/REGEX/ s/^/>/; s/\t/ /g' Makefile

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.