为什么 sed 做的事情比我要求的还要多?

为什么 sed 做的事情比我要求的还要多?

当我应用sed -i -e "s/..\///" -e "s/type_properties\///" testfile到以下文件时:

#include "../../../../include/concepts/type_properties/operations/has_or_op_v.hpp"

int main() {
    // Test has_not_op_v.
}

它输出这个:

#include "../../../include/concepts/operations/has_or_op_v.hpp"

int main() {
  / Test has_not_op_v.
}

我只是想让 sed 删除一个../并删除type_properties/,但这也破坏了我的注释。

答案1

该角色.是一个元字符。这意味着它具有特殊的意义。.意思是“匹配任何单个字母或字符”。您只想匹配文字.字符。

如果更改.\.,您将得到正确的输出。

例子:

sed -i -e "s/..\///" -e "s/type_properties\///" testfile

变成:

sed -i -e "s/\.\.\///" -e "s/type_properties\///" testfile

答案2

首先,不要sed -i在测试时使用。不先运行-i并检查结果。当你知道它看起来正确时然后添加-i将更改就地提交到文件。

原因sed似乎比要求做的更多,因为main()函数中的注释与两个表达式中的第一个匹配..\/(两个字符和一个斜杠)。

如果您知道您只想将更改应用于以 开头的行#include,那么您可以使用

sed -e '/^#include/{s%\.\./%%; s%type_properties/%%;}' file.c

此处,仅在以字符串 开头的行上执行两次替换#include。我还正确转义了第一个表达式中的两个点,以便它们匹配点,而不是“任何字符”。由于我们匹配的文本包含斜杠,因此我还选择%s命令中使用替代分隔符 。

相关内容