【问题标题】:sed replace token in a multiline file with the contents of another filesed 用另一个文件的内容替换多行文件中的标记
【发布时间】:2021-04-26 14:40:46
【问题描述】:

文件 1:

<!doctype html><html lang="en"><head><meta name="REPLACE_ME"></head><body></body></html>

文件 2:

<meta name="A" content="A1"><meta name="B" content="B1">

我正在尝试将File 1 中的&lt;meta name="REPLACE_ME"&gt; 替换为File 2 的全部内容。

预期结果:

<!doctype html><html lang="en"><head><meta name="A" content="A1"><meta name="B" content="B1"></head><body></body></html>

如果File 1 有多行,我可以使用这样的东西:

TOKEN="<meta name=\\\"REPLACE_ME\\\">"
sed -e "/${TOKEN}/r file2" -e "/${TOKEN}/d" file1

我遇到的问题是当File 1 中的内容不在单独的行上 时,如何使用sed 执行此操作。

这是我最后一次尝试:

TOKEN="<meta name=\\\"REPLACE_ME\\\">"
sed "s/${TOKEN}/$(sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' file2 | tr -d '\n')/" file1

但是,它很时髦并使用我想避免的tr。任何帮助将不胜感激。

【问题讨论】:

  • 您不应该使用面向行的工具来解析/修改 XML/HTML。最好将示例更改为纯文本、非结构化文本以规避反对意见。

标签: regex bash shell unix sed


【解决方案1】:

正如其他人评论的那样,您应该为此使用专用的 html 解析器,但您的示例数据有限,可以使用 sed 实现您所需要的:

sed -zrn 's@\n@@g;s@(^.*<head>)('"$TOKEN"')(</head>.*</html>)(<meta.*$)@\1\4\3@p' <(cat file1 file2)

将单个输入流重定向到 sed 并作为一行使用 (-z) 首先删除所有换行符,然后使用正则表达式(-r 或 -E)并利用变量 TOKEN 将行拆分为括号中描述的 4 部分.将第 1 部分的行替换为 4 和 3。

我知道没有必要使用 cat 作为一个流进行定向,因为 sed 应该将文件视为一个流,除非使用 -s 但我在拆分行时遇到了问题。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -E 's/(.*)<meta name="REPLACE_ME">(.*)/echo "\1$(cat file2)\2"/e' file1
    

    &lt;meta name="REPLACE_ME"&gt; 上匹配并使用反向引用来收集匹配两侧的数据。然后评估并回显一个由反向引用和夹在它们之间的 file2 组成的字符串。

    【讨论】:

      猜你喜欢
      • 2014-03-15
      • 1970-01-01
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2018-07-21
      • 1970-01-01
      • 2021-10-04
      相关资源
      最近更新 更多