我有以下测试文件
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: `/'
有什么想法可以实现这一目标吗?
假设您没有任何带有多个#
s 的行,这将起作用:
sed -e '/BBB/ s/^#*/#/' -i file
注意:您不需要 /g 因为您每行最多进行一次替换。
我发现这个解决方案效果最好。
sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
不管有多少个“#”符号,它都不会再添加一个。如果您要搜索的模式不包含“#”,它会将其添加到行首,并且还会添加一个尾随空格。
如果您不想要尾随空格
sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\1/' file
另一种具有&
特殊字符的解决方案,它引用了模式空间的整个匹配部分。它比捕获和引用正则表达式组更简单/更干净。
sed -i 's/^[^#]*BBB/#&/' file
假设 BBB 位于一行的开头,我最终使用了一个更简单的表达式:
sed -e '/^BBB/s/^/#/' -i file
给未来的我再写一张。不要忽视-i
. 因为这行不通:sed -e "..." same_file > same_file
.
实际上,您不需要感叹号 (!),因为插入符号已经否定了方括号内的任何内容,并将忽略搜索中的所有哈希符号。这个例子对我有用:
sed -i '/[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
评论所有“BBB”,如果它还没有评论。
sed -i '/BBB/s/^#\?/#/' file
sed -i '/![^#]/ s/\(^.*BBB.*$\)/#\ \1/' file
这对关键字不起作用*.sudo
,根本没有评论......
只有以下语法有效:
sed -e '/sudo/ s/^#*/#/' file
在对原始副本进行更改之前,我通常会提供sed
备份文件:-i.bak
sed -i.bak '/BBB/ s/^#*/#/' file
这样,完成后,我同时拥有file
并且只有在我有信心之后file.bak
才能决定删除。file.bak
如果您不仅要注释掉“BBB”的完全匹配,还要注释掉中间某处有“BBB”的行,您可以使用以下解决方案:
sed -E '/^([^#].*)?BBB/ s/^/#/'
这不会更改任何已注释掉的字符串。