ChatGPT解决这个技术问题 Extra ChatGPT

sed - 注释与特定字符串匹配且尚未注释掉的行

我有以下测试文件

AAA
BBB
CCC

使用以下 sed 我可以注释掉 BBB 行。

# sed -e '/BBB/s/^/#/g' -i file

如果它在开头没有#,我只想注释掉它。

# sed -e '/^#/! /BBB/s/^/#/g' file

sed: -e expression #1, char 7: unknown command: `/'

有什么想法可以实现这一目标吗?


H
Hasturkun

假设您没有任何包含多个 # 的行,这将起作用:

sed -e '/BBB/ s/^#*/#/' -i file

注意:您不需要 /g 因为您每行最多进行一次替换。


这将始终将匹配行编辑为以单个 # 开头。因此,如果它在此命令之后以三个 # 开头,它将“清理”它以仅以一个 # 开头。如果出现问题,要缓解此问题,只需相应地更改匹配部分(例如 sed -e '/^BBB/...)
sed '/^#BBB/' 你的意思是。但是,如果 BBB 位于中间的某个位置,则它将不起作用。有一个编写 sed '/^#/! {/BBB/ s/^/#/}' 的选项会更好,但只要您知道它的局限性,我的初始解决方案就更简单了。
如果我们在 java 程序中使用上述方法,如何避免这种情况?
像这样:sed -e '/BBB/ s|^(//)*|//|' -i file。请注意,它仅适用于单个类似的评论,假设评论从行首开始,并将 // 的多个 pairs 替换为单个 //
是否可以将 BBB 放入输入变量中?
a
agostonbarna

另一种带有 & 特殊字符的解决方案,它引用了模式空间的整个匹配部分。它比捕获和引用正则表达式组更简单/更干净。

sed -i 's/^[^#]*BBB/#&/' file

太好了,谢谢!
o
oguz ismail

我发现这个解决方案效果最好。

sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file

不管有多少个“#”符号,它都不会再添加一个。如果您要搜索的模式不包含“#”,它会将其添加到行首,并且还会添加一个尾随空格。

如果您不想要尾随空格

sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\1/' file

您可能想要替换“!”使用“^”,否则这是比官方答案更好的解决方案
R
RayLuo

假设 BBB 位于一行的开头,我最终使用了一个更简单的表达式:

sed -e '/^BBB/s/^/#/' -i file

给未来的我再写一张。不要忽视-i。因为这不起作用:sed -e "..." same_file > same_file


B
Bilal

sed -i '/![^#]/ s/\(^.*BBB.*$\)/#\ \1/' file

这不适用于关键字 *.sudo,根本没有评论...

只有以下语法有效:sed -e '/sudo/ s/^#*/#/' file


I
Ibo

实际上,您不需要感叹号 (!),因为插入符号已经否定了方括号内的任何内容,并将忽略搜索中的所有哈希符号。这个例子对我有用:

sed -i '/[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file


Г
Геннадий Аполлонов

评论所有“BBB”,如果它还没有评论。

sed -i '/BBB/s/^#\?/#/' file

A
Abolfazl Shahbazi

在对原始副本进行更改之前,我通常会提供 sed-i.bak 来备份文件:

sed -i.bak '/BBB/ s/^#*/#/' file

这样完成后,我同时拥有 filefile.bak,只有在我有信心之后才能决定删除 file.bak


P
P. D

如果您不仅要注释掉“BBB”的完全匹配,还要注释掉中间某处有“BBB”的行,您可以使用以下解决方案:

sed -E '/^([^#].*)?BBB/  s/^/#/'

这不会更改任何已注释掉的字符串。