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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17998763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:26:27  来源:igfitidea点击:

sed - Commenting a line matching a specific string AND that is not already commented out

regexlinuxunixsed

提问by Jean-Francois Chevrette

I have the following test file

我有以下测试文件

AAA
BBB
CCC

Using the following sed I can comment out the BBBline.

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

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

I'd like to only comment out the line if it does not already has a # at the begining.

如果开头还没有#,我只想注释掉该行。

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

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

Any ideas how I can achieve this?

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

采纳答案by aragaer

Assuming you don't have any lines with multiple #s this would work:

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

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

Note: you don't need /g since you are doing at most one substitution per line.

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

回答by Bobbert Waitforit Hurny

I find this solution to work the best.

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

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

It doesn't matter how many "#" symbols there are, it will never add another one. If the pattern you're searching for does not include a "#" it will add it to the beginning of the line, and it will also add a trailing space.

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

If you don't want a trailing space

如果您不想要尾随空格

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

回答by Bill

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

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

This doesn't work for me with the keyword *.sudo, no comments at all...

这对我的关键字不起作用*.sudo,根本没有评论......

Ony the syntax below works: sed -e '/sudo/ s/^#*/#/' file

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

回答by Dwayne Mcnab

Actually, you don't need the exclamation sign (!) as the caret symbol already negates whatever is inside the square brackets and will ignore all hash symbol from your search. This example worked for me:

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

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

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

回答by agostonbarna

Another solution with the &special character which references the whole matched portion of the pattern space. It's a bit simpler/cleaner than capturing and referencing a regexp group.

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

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

回答by RayLuo

Assuming the BBB is at the beginning of a line, I ended up using an even simpler expression:

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

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

One more note for the future me. Do not overlook the -i. Because this won't work: sed -e "..." same_file > same_file.

给未来的我多一份笔记。不要忽视-i. 因为这是行不通的:sed -e "..." same_file > same_file