【问题标题】:sed regex find and replace in file (macOS)sed 正则表达式在文件中查找和替换 (macOS)
【发布时间】:2020-04-22 17:15:18
【问题描述】:

我在使用 sed 替换文件中的行时遇到了一些问题。 我想要的是使用正则表达式将所有出现的#include <path/to/my/file.h>#include "file.h" 切换出去。

当我用 echo 测试它时,它会给出我正在寻找的输出:

echo "#include <path/to/my/file.h>" | sed -E 's/^(#include.*[\/<])([^\/\<]*\.h)(>)$/#include \"\2\"/g'

但是当我使用包含#includes 的文件运行它时,它什么也没有改变。我觉得我已经尝试了所有可以在网上找到的东西,但没有任何区别

这是我尝试更改文件中的行时使用的行:

sed -E -i '' 's/^(#include.*[\/<])([^\/\<]*\.h)(>)$/#include \"\2\"/g' /path/to/my/file.h

编辑: 通过在正则表达式语句的开头和结尾删除 ^ 和 $ 来修复

【问题讨论】:

  • 错误信息是什么?
  • ‘’ 替换为''
  • 我认为你应该删除''
  • 您能分享您的源文件(#include)以便我们重现吗?
  • 如果您的换行符让您感到困惑,您可以尝试删除 sed 替换左侧开头的 ^ 和结尾的 $:sed -E 's/(#include.*[\/&lt;])([^\/\&lt;]*\.h)(&gt;)/#include \"\2\"/g' 它不应该导致额外的行会受到影响,除非您有带有#include 的数据字符串。

标签: macos sed terminal


【解决方案1】:

似乎 OP 正则表达式中的行首或行尾锚点不匹配......可能是因为源文件在行尾不遵循 MacOS 标准。 MacOS(在 OS X 之前)使用 \r,而 Windows 使用 \r\n,而 linux 和 OS X 仅使用 \n。因此,一旦 OP 删除了正则表达式中的行首或行尾锚点,它们的表达式就会匹配并发生替换。

没有行开始/结束锚点的 OP 正则表达式:

sed -E 's/(#include.*[\/<])([^\/\<]*\.h)(>)/#include \"\2\"/g'

风险在于,如果其中有其他带有#include &lt;path/to/some/file.h&gt; 的行,这些行也会在不应该被替换时被替换。不过这不太可能。

OP 可以判断这是否可能是问题的一种方法是将一些带有和不带有问题行的文本样本发送到十六进制转储或八进制转储程序。我们知道echo '#include &lt;path/to/my/file.h&gt;' 的输出中没有任何奇怪的换行符(因为 sed 使用了行尾锚点),我们可以检查它对行尾的影响:

echo '#include <path/to/my/file.h>' | od -cx

我们可以将这些行尾与以下行尾进行比较:

cat afi.h | od -cx | head -30

【讨论】:

    【解决方案2】:

    基于:In-place edits with sed on OS X

    请注意,MacOS 不支持无后缀的“-i”(也称为“就地编辑”)。根据引用的问题,尝试使用临时后缀(本例中为 .orig)

    sed -E -i '.orig' 's/^(#include.*[\/<])([^\/\<]*\.h)(>)$/#include \"\2\"/g' /path/to/my/file.h
    rm -f /path/to/my/file.h.orig
    

    【讨论】:

    • 当他们进行不同的替换时,-i 选项适用于 OP: sed -E -i '' 's/Dmi/substituteWord/g' /path/to/my/file.h 问题是他原来的替换不匹配。
    【解决方案3】:

    试试这个简单的sed 替换:

    echo "#include <path/to/my/file.h>" |sed -r 's|<[^>]+file.h>|"file.h"|'
    

    输出

    #include "file.h"
    

    解释:

    sed -r 使用带有扩展正则表达式的 sed

    's|source-pattern|target-pattern| 替换命令使用| 作为分隔符(而不是普通的/

    &lt;[^&gt;]+file.h&gt;正则表达式匹配>](不止一次)file.h>

    "file.h" 目标正则表达式匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 1970-01-01
      • 2018-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      相关资源
      最近更新 更多