【问题标题】:Match Multiple Strings In Awk Command Using RS And RT使用 RS 和 RT 匹配 awk 命令中的多个字符串
【发布时间】:2016-10-15 06:17:35
【问题描述】:

我有以下数据:

Example line 0</span>
<tag>Example line 1</tag>
<span>Example line 1.5</span>
--Hello Example line 1.7
<tag>
Example line 2
</tag>
--Hello Example line 2.7
<span>Example line 4</span>

使用这个命令awk -v RS='&lt;/tag&gt;' 'RT {gsub(/.*?&lt;tag&gt;|\n/, ""); print "&lt;tag&gt;" $0 RT}'我得到:

<tag>Example line 1</tag>
<tag>Example line 2</tag>

但是,我希望输出是:

<tag>Example line 1</tag>
--Hello Example line 1.7
<tag>Example line 2</tag>
--Hello Example line 2.7

问题:

我只想知道如何添加“或”选项以匹配以--Hello 开头的任何行。在我的代码中实现的正确方法是什么?

其他选项:

或者,另一种选择是使用grep -o '&lt;tag.*tag&gt;\|^--.*',但我还需要找到一种匹配换行符的方法(如此处所问:Match Anything In Between Strings For Linux Grep Command)。

非常感谢任何帮助。

【问题讨论】:

  • 您好@EdMorton,请注意。我也愿意接受其他解决方案:-)
  • 好的,我发布了一个解决方案。顺便说一句,无论您认为.*? 是什么意思,您都错了,因为这只是 ERE 正则表达式的废话。如果您告诉我们您认为它会做什么,我们可以告诉您如何在 awk 中执行任何操作。

标签: linux bash unix awk grep


【解决方案1】:

您可以将之前的 awk 命令修改为:

awk -v RS='</tag>' '/\n--Hello /{print gensub(/.*\n(--Hello [^\n]*).*/, "\\1", "1")}
       RT{gsub(/.*<tag>|\n/, ""); print "<tag>" $0 RT}' file

<tag>Example line 1</tag>
--Hello Example line 1.7
<tag>Example line 2</tag>
--Hello Example line 2.7

【讨论】:

  • 我应该在命令中保留换行符还是保留一行?
  • 其实没关系,你也可以全部放在一行里。
【解决方案2】:
$ cat tst.awk
BEGIN { RS="--Hello[^\\n]+|<\\/tag>" }
RT { print (RT~/^--/ ? "" : gensub(/.*(<tag>)/,"\\1",1)) RT }

$ awk -f tst.awk file
<tag>Example line 1</tag>
--Hello Example line 1.7
<tag>
Example line 2
</tag>
--Hello Example line 2.7

以上使用 GNU awk 处理多字符 RS、RT 和 gensub()。

【讨论】:

  • 当然。任何语言的任何长度的任何程序都可以在 1 行上编写。
  • 嗨,埃德,这很酷。很高兴知道。对于我们这些刚刚在工作中学习并且没有适当的 IT 背景或编程学位的人来说,这些答案和见解有助于填补我们的知识空白。感谢您的贡献和帮助。对于像我这样的人,您的技能将受到高度赞赏:-)
猜你喜欢
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多