Bash 输出两个相邻的结果

Bash 输出两个相邻的结果

我有一个来自 xmllint 和 egrep 的输出,我想打印两个相邻的字段。例如

(xmlinput) xmllint --format | egrep reference\|sourcefile
<reference>ItemX</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>

有没有办法将引用和源文件元素彼此相邻输出?例如

(xmlinput) xmllint --format | egrep reference\|sourcefile 
<reference>ItemX</reference><sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference><sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference><sourcefile>://filepath/blah/blah/</sourcefile>

答案1

[your command] | paste -d '' - -

将连接连续的行。

答案2

一旦开始使用grepXML,您就会对输入做出假设,并且(几乎肯定)您将不再拥有有效的 XML 输出,因此有时这不是最好的方法。

也就是说,阻力最小的路径通常涉及grep,因此取决于您的 XML(格式良好的最小示例会很有用),您应该能够使用xmllintwith --xpathxmllint>= 2.7.7 以获得--xpath支持),如下所示:

xmllint --xpath "//reference|//sourcefile"  input.xml |
  pcregrep -o "(<reference>.*?</sourcefile>)"

其中xmllint使用提取元素X路径|与您感兴趣的元素之一(作为逻辑“或”)匹配的表达式(//以选择输入中任意位置的所有匹配元素)。 (非 XML 感知)pcregrep(而不是egrep)将每对元素与分组进行匹配,并每行输出每个匹配的组。这里需要注意的一点是正则表达式,.*?它是 PCRE非贪婪匹配所以它匹配最低限度指示标签之间的文本量,而不是一次性整行(xmllint --xpath ...将所有内容转储到一行)。

使用 grep 有点“作弊”,我们对输入进行假设,但xmllint完成了大部分繁重的工作。这种方法可能会导致未来的解析问题,因为XML 不是“常规的”正则表达式并不是完成这项工作的最佳工具。

做到这一点的巧妙方法是XML小星:

xml select -t -m '//*' \
  --if 'local-name()="reference"' -c . \
  --elif 'local-name()="sourcefile"' -c . -o $'\n' input.xml

这会搜索所有元素 ( //*),匹配时<reference>将该节点复制到输出 ( -c .),否则匹配时<sourcefile>将该节点复制到带有额外换行输出 ( -o $'\n') 的输出。

答案3

只需将数据通过管道传输到perl -pe 'chop if /^<reference>/'

相关内容