【问题标题】:How to replace word with multiple lines如何用多行替换单词
【发布时间】:2014-03-11 16:33:05
【问题描述】:

我看过很多类似的问题和答案,但都碰壁了。

我有一个这样的 XML 文件:

<blah:formProperty id="_blah" default="%HTML%">

我需要将 %HTML% 替换为大约 200 多行,如下所示:

&lt;style&gt;
blah
&lt;/style&gt;
&lt;script&gt;
blah
&lt;/script&gt;

使用 sed 会引发错误,因为它不喜欢多行。

awk 似乎是一个更好的选择,但不知道如何完成它。

Replace a word with multiple lines using sed? 很接近,但我无法让 awk 示例工作。如何定义 $DATA 以使 'echo $DATA' 返回多行?大量关于此的论坛主题都说只有

echo "$DATA" 

将打印多行。

所以这真的是一个两部分的问题。我该如何解决我上面的问题?他们是如何让这个 awk 示例发挥作用的?

【问题讨论】:

  • 如果 DATA 中有多行,那么echo "$DATA" 将打印多行!试试DATA="$(printf "multi\nline\ndata\n")"
  • 你在哪个平台上?并非所有awks 都是平等的。
  • 我在 Mac 上。我上面给出的链接有 echo $DATA 然后显示多行输出 - 永远无法重新创建。
  • @PaulEricson 可能是错字,因为当您打印不带引号的字符串时,换行符会转换为空格。

标签: macos sed awk


【解决方案1】:

如何定义 $DATA 以使 'echo $DATA' 返回多行?

引用您的多行文本。例如:

$ DATA='&lt;style&gt;
blah
&lt;/style&gt;
&lt;script&gt;
blah
&lt;/script&gt;'

现在如果你 echo 变量,你会得到

$ echo "$DATA"
&lt;style&gt;
blah
&lt;/style&gt;
&lt;script&gt;
blah
&lt;/script&gt;

awk 似乎是一个更好的选择,但不知道如何完成它。

现在您已经定义了一个变量,您可以在awk 中使用该变量,方法是:

awk -v var="$DATA" '{sub(/%HTML%/,var)}1' file.xml 

$ cat file.xml 
h:formProperty id="_blah" default="%HTML%">

$ awk -v var="$DATA" '{sub(/%HTML%/,var)}1' file.xml 
h:formProperty id="_blah" default="%HTML%lt;style%HTML%gt;
blah
%HTML%lt;/style%HTML%gt;
%HTML%lt;script%HTML%gt;
blah
%HTML%lt;/script%HTML%gt;">

现在您一定想知道为什么在替换中得到%HTML%。这是因为有一个特殊字符&amp; 告诉sub 函数生成匹配的文本,在我们的例子中是%HTML%。为了避免这种情况,你需要逃避它。使用\\ 将允许sub 放置文字&amp;。使用 \&amp; 被视为普通的 &amp;,您也不想要。

$ DATA='\\&lt;style\\&gt;
blah
\\&lt;/style\\&gt;
\\&lt;script\\&gt;
blah
\\&lt;/script\\&gt;'

$ awk -v var="$DATA" '{sub(/%HTML%/,var)}1' file.xml 
h:formProperty id="_blah" default="&lt;style&gt;
blah
&lt;/style&gt;
&lt;script&gt;
blah
&lt;/script&gt;”>

更新:

正如 OP 所说,他在 OSX 上使用 awk 不接受带有嵌入式换行符的变量,并按照 cmets 中 mklement0 的建议更新答案。

awk -v var="${DATA//$'\n'/\\n}" '{sub(/%HTML%/,var)}1' file.xml 

【讨论】:

  • 您将 var 包装在 dbl 引号中以供回显。这不是我给出的例子所做的。我问如何让 echo 显示没有双引号的多行 var。
  • 我在 \\&s 和 awk 中遇到此错误:awk: newline in string \\<style\\> #p... 在源代码行 1。这与我在使用 sed 时遇到的错误基本相同。
  • @PaulEricson:根据定义使用不带引号的变量引用会用空格替换换行符(分词)。您的问题是 OSX awk(与 @jaypalsingh 假设的 gawk 不同)不接受带有嵌入换行符的变量。您可以通过将 -v var="${DATA//$'\n'/\\n}" 传递给 awk 来解决此问题 - 不过,您仍然需要按照此答案中的说明转义 &amp; 字符。
  • @mklement0 感谢您的解决方法。我可能应该提到使用的答案gawk
  • 所以之前的错误是数据只有 \&。当我将数据更改为具有 \\&.我收到此错误:awk:字符串中的换行符 \\\<style\\\> ...在源代码行 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多