简体   繁体   English

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

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

I have the following test file我有以下测试文件

AAA
BBB
CCC

Using the following sed I can comment out the BBB line.使用以下 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?有什么想法可以实现吗?

Assuming you don't have any lines with multiple # s this would work:假设您没有任何带有多个#的行,这将起作用:

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

Note: you don't need /g since you are doing at most one substitution per line.注意:您不需要 /g,因为您每行最多进行一次替换。

I find this solution to work the best.我发现这个解决方案效果最好。

sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\ \1/' 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.*$\)/#\1/' file

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

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 .不要忽视-i Because this won't work: sed -e "..." same_file > same_file .因为这不起作用: sed -e "..." same_file > same_file

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

This doesn't work for me with the keyword *.sudo , no comments at all...这对关键字*.sudo对我*.sudo ,根本没有评论......

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

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

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

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

If BBB is at the beginning of the line:如果BBB在行首:

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

If BBB is in the middle of the line:如果BBB在线的中间:

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

I'd usually supply sed with -i.bak to backup the file prior to making changes to the original copy:在对原始副本进行更改之前,我通常会提供带有-i.bak sed来备份文件:

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

This way when done, I have both file and file.bak and I can decide to delete file.bak only after I'm confident.这样完成后,我同时拥有filefile.bak ,只有在我有信心后才能决定删除file.bak

If you want to comment out not only exact matches for 'BBB' but also lines that have 'BBB' somewhere in the middle, you can go with following solution:如果您不仅要注释掉 'BBB' 的完全匹配项,还想注释掉中间某处带有 'BBB' 的行,您可以使用以下解决方案:

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

This won't change any strings that are already commented out.这不会更改任何已注释掉的字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM