我有一个字符串
/abc/gef \*(cse,fff)
要从文件中删除,必须匹配完整的字符串模式,尝试使用
sed -i '//abc/gef \*(cse,fff)/d' filename
但这会导致错误:
sed:-e 表达式 #1,字符 xx:预期 sed 的较新版本
我还尝试了以下选项但没有成功:
sed -i '/\/abc\/gef \*(cse,fff)/d' filename
sed -i 's|/abc/gef \*(cse,fff)||g' filename
正确的命令是什么?
答案1
以下适用于 GNU sed 版本 4.5 和 4.7,并将删除包含该字符串的任何行:
sed '/\/abc\/gef \\\*(cse,fff)/d' file
您必须使用\
转义/
字符串中的两个实例,以便它们不会被视为分隔符,*
否则会扩展为它之前的字符f
。后者会导致它与字符串不匹配。
s
如果您只想删除整个文件中的字符串本身而不是整个行,您还可以使用允许其他字符作为分隔符的选项:
sed 's|/abc/gef \\\*(cse,fff)||g' file
它用作|
分隔符,这样您就不必转义/
。
要在确定文件符合您的要求后就地编辑该文件,您可以-i
像上面那样使用:
sed -i '/\/abc\/gef \\\*(cse,fff)/d' file
sed -i 's|/abc/gef \\\*(cse,fff)||g' file
编辑:我已经更新了答案,因为问题中的字符串与最初发布时的字符串不同。
答案2
问题是\
(转义字符)和*
(0或更多)在正则表达式中都有特殊含义,所以你需要逃脱以便将它们用作文字字符。现在,逃避某些东西的方法是在\
它前面添加一个。因此,为了*
匹配字面星号而不是表示“0 或更多”,您可以编写\*
.同样,为了逃避\
你可以写\\
.把这些放在一起,我们有:
$ cat file
foo
bar
/abc/gef \*(cse,fff)
baz
和:
$ sed '/\/abc\/gef \\\*(cse,fff)/d' file
foo
bar
baz
请注意我如何转义了/
since //
is 中的匹配运算符sed
。这就是我们有/\/abc\/gef
和没有的原因//abc/gef
。d
末尾的 表示“删除与此模式匹配的任何行” 。
答案3
这听起来像是 grep 的工作:
$ cat file
line 1
line 2
/abc/gef *(cse,fff)
line 4
$ grep -Fxv '/abc/gef *(cse,fff)' file
line 1
line 2
line 4