我有一个配置文件,我想替换包含特定字符串的行,比如说测试:
文件配置文件
aaa
bbb
ccc
// test
ddd
// test
我的代码行不起作用,我是新手 sed。
sed -i `s#^//[ \t]test#test#g'
有什么指导吗?
答案1
首先,我建议避免使用,-i
因为它会在未经确认的情况下替换文件。
这是您尝试完成并输出到标准输出(终端)的工作版本:
sed 's#^//[ \t]test$#test#g' file.conf
aaa
bbb
ccc
test
ddd
test
可选择通过附加的方式将其通过 less 管道传输,| less
以便能够对大量输出进行分页。
以上内容都是针对的序列非常具体的test
,因此为了更概括,您可以尝试以下操作:
sed 's#^//\s\(.*\)$#\1#g' file.conf
它将删除该//
部分和任何空格,直到实际文本,无论该文本是什么。
如果您喜欢结果,您可以-i
再次添加标志来替换文件。
为了进一步说明您的尝试并解释为什么我的示例有效:
sed -i `s#^//[ \t]test#test#g'
- 您使用的反引号 (`) 由您的 shell 而不是 Sed 解释。
'
这里可能应该使用简单的单引号 ( )。 - 井号 (
#
) 是您选择的分隔符,它是常见正斜杠 (/
) 的良好替代品,因为您的匹配是关于同一个字符,这样就避免了转义的需要。 命令中的模式
s/regexp/replacement/
是标准模式,如手册页中所述,其中包括man 1 sed
::s/regexp/replacement/
尝试将正则表达式与模式空间进行匹配。如果成功,则用替换替换匹配的部分。替换可能包含特殊字符
&
以引用模式空间中匹配的部分,特殊转义符\1
则\9
引用正则表达式中相应的匹配子表达式。rexexp
上面的是常用表达。- 正则表达式
^//[ \t]test$
匹配^
以两个正斜杠 ( ) 开头,后跟一个空格的行或者制表符,后跟精确的序列test
和行尾 ($
)。 - 该
g
标志以全局方式执行此操作,如所解释的那样这里。 - 缺少输入文件,应在 Sed 命令后给出。
答案2
你做不是必须使用正斜杠作为分隔符。事实上,为了便于阅读,我建议使用逗号或井号等其他分隔符。
-i
也是你的朋友,但只有当你确信它是正确的时候才使用它。在这种情况下,我会这样做:
sed -r 's,^//[ \t]*(.+),\1,' file.conf | less
我-r
在这里使用扩展正则表达式,这样我就不必转义括号了。此外,它还允许我使用加号运算符,表示“一次或多次出现”。以下表达式是等效的:
sed 's,^//[ \t]*\(..*\),\1,' file.conf | less
(一个点匹配至少一个字符,后跟零个或多个任意字符)
在我确定替换正确后(在less
搜索中输入斜线和关键字),我通过输入关闭 less q
,然后按向上键导航到上一个历史记录条目。然后我删除| less
并输入-i
以继续替换:
sed -r 's,^//[ \t]*(.+),\1,' file.conf -i
如果您想更深入地了解 sed,我建议您阅读 sed 的信息页,它比手册页更详细:
info sed