gpt4 book ai didi

command-line - 如何使用 sed 仅替换文件中的第一次出现?

转载 作者:太空宇宙 更新时间:2023-11-04 12:11:56 26 4
gpt4 key购买 nike

我想在任何现有 #includes 之前使用额外的 include 指令更新大量 C++ 源文件。对于这类任务,我通常使用带有 sed 的小型 bash 脚本来重写文件。

如何让 sed 只替换文件中第一次出现的字符串,而不是每次都替换?

如果我用

sed s/#include/#include "newfile.h"\n#include/

它取代了所有#includes。

也欢迎提出实现相同目标的替代建议。

最佳答案

sed 脚本,只会用“Banana”替换第一次出现的“Apple”

例子

     Input:      Output:

Apple Banana
Apple Apple
Orange Orange
Apple Apple

这是一个简单的脚本:编者注:仅适用于 GNU sed

sed '0,/Apple/{s/Apple/Banana/}' input_filename

前两个参数0/Apple/是范围说明符。 s/Apple/Banana/ 是在该范围内执行的。因此,在这种情况下,“在开始 (0) 到 Apple 的第一个实例的范围内,将 Apple 替换为 Banana 。只有第一个 Apple 会被替换。

背景:在传统的 sed 中,范围说明符是 also “从这里开始”和“从这里结束”(含)。然而,最低的“开始”是第一行(第 1 行),如果“在这里结束”是正则表达式,那么它只会尝试在“开始”之后的下一行进行匹配,所以最早可能的结束是行2. 因此,由于范围是包容性的,最小的可能范围是“2 行”,最小的起始范围是第 1 行和第 2 行(即,如果第 1 行出现,第 2 行的出现也将被更改,在这种情况下不需要). GNU sed 添加了自己的扩展,允许将开始指定为“伪”第 0 行,以便范围的结尾可以是 第 1 行,如果正则表达式匹配第一行,则允许它在“仅第一行”范围内。

或者简化版(一个空的RE比如//意味着重新使用之前指定的那个,所以这是等价的):

sed '0,/Apple/{s//Banana/}' input_filename

大括号是optional对于 s 命令,所以这也是等价的:

sed '0,/Apple/s//Banana/' input_filename

所有这些仅适用于 GNU sed

您还可以使用自制软件 brew install gnu-sed 在 OS X 上安装 GNU sed。

关于command-line - 如何使用 sed 仅替换文件中的第一次出现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48609015/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com