具有特定文本的多行 grep
Multiline grep with specific text
有一个 xml 文件,里面有很多 <A_tag>
-s。
我需要查看至少有一个 <C_tag>
.
的那些 A 标签(及其子标签,因此标签的全部内容)
所以这个块应该匹配(因此包含在结果中):
<A_tag>
...
...
<C_tag attr1="" ... attrn="" />
...
</A_tag>
我试过使用 pcregrep,但我不知道如何判断任何块结尾,它比 1 个字符长(</A_tag>
比那个长,但是例如 [^>]
正则表达式对我来说也很容易)。
我也试过 awk,但也无法达到目标。
如果有经验的人可以帮助我,请让你的命令也用空行分隔找到的块,这样我可以学到更多。
跟进 xmllint 评论:
xmllint --xpath '(//A_tag/C_tag/..)' x.xml
会在A_TAG下寻找C_TAG,然后显示父A_TAG。
输出:
<A_tag>
<C_tag attr1="" attrn=""/>
</A_tag>
是的,就我而言,这就是解决方案:
xmllint --shell x.xml <<< 'xpath //A_tag//C_tag/ancestor::A_tag'
因为我的xmllint
版本不支持--xpath
选项。
此外,C_tag
可以是 A_tag
的任何后代,而不仅仅是直接 child(我没有在问题中澄清)。
但是,dash-o的答案似乎是正确的。
我唯一的问题是我正在使用的这个 xml 文件包含 450 万行,其中 xmllint
结果很慢 - 因为它确实解析了文件。
如果您有适用于 awk
或 pcregrep
的更通用的解决方案,请与我分享。他们在这里会很好,因为他们只处理模式。
要不然我明天就采纳原答案了
如果文件打印精美(或遵循类似规则),可以编写小的 awk 脚本,并且只作用于 a_tag 和 c_tag 行:
awk '
/<A_tag>/ { in_a=[=10=] ; c="" ; next }
in_a { in_a = in_a RS [=10=]}
/<C_tag/ { c=[=10=] ; next }
/<\/A_tag>/ { if ( in_a && c ) { print in_a ; in_a="" ; c=""} }
' x.xml
有一个 xml 文件,里面有很多 <A_tag>
-s。
我需要查看至少有一个 <C_tag>
.
所以这个块应该匹配(因此包含在结果中):
<A_tag>
...
...
<C_tag attr1="" ... attrn="" />
...
</A_tag>
我试过使用 pcregrep,但我不知道如何判断任何块结尾,它比 1 个字符长(</A_tag>
比那个长,但是例如 [^>]
正则表达式对我来说也很容易)。
我也试过 awk,但也无法达到目标。
如果有经验的人可以帮助我,请让你的命令也用空行分隔找到的块,这样我可以学到更多。
跟进 xmllint 评论:
xmllint --xpath '(//A_tag/C_tag/..)' x.xml
会在A_TAG下寻找C_TAG,然后显示父A_TAG。
输出:
<A_tag>
<C_tag attr1="" attrn=""/>
</A_tag>
是的,就我而言,这就是解决方案:
xmllint --shell x.xml <<< 'xpath //A_tag//C_tag/ancestor::A_tag'
因为我的xmllint
版本不支持--xpath
选项。
此外,C_tag
可以是 A_tag
的任何后代,而不仅仅是直接 child(我没有在问题中澄清)。
但是,dash-o的答案似乎是正确的。
我唯一的问题是我正在使用的这个 xml 文件包含 450 万行,其中 xmllint
结果很慢 - 因为它确实解析了文件。
如果您有适用于 awk
或 pcregrep
的更通用的解决方案,请与我分享。他们在这里会很好,因为他们只处理模式。
要不然我明天就采纳原答案了
如果文件打印精美(或遵循类似规则),可以编写小的 awk 脚本,并且只作用于 a_tag 和 c_tag 行:
awk '
/<A_tag>/ { in_a=[=10=] ; c="" ; next }
in_a { in_a = in_a RS [=10=]}
/<C_tag/ { c=[=10=] ; next }
/<\/A_tag>/ { if ( in_a && c ) { print in_a ; in_a="" ; c=""} }
' x.xml