如何在 XML 文件中找到特定的标签部分?

use*_*795 4 grep xml text-processing

我的文件的最后几行/usr/share/glib-2.0/schemas/org.gnome.Vino.gschema.xml

<schemalist>
  <schema>
   <!-- some other tags -->

    <key name='notify-on-connect' type='b'>
      <summary>Notify on connect</summary>
      <description>
        If true, show a notification when a user connects to the system.
      </description>
      <default>true</default>
    </key>

    <key name='enabled' type='b'>
      <summary>Enable remote access to the desktop</summary>
      <description>
      If true, allows remote access to the desktop via the RFB
      protocol. Users on remote machines may then connect to the
      desktop using a VNC viewer.
      </description>
      <default>false</default>
    </key>
  </schema>
</schemalist>
Run Code Online (Sandbox Code Playgroud)

如果我想grep这一段:

<key name='enabled' type='b'>
  <summary>Enable remote access to the desktop</summary>
  <description>
  If true, allows remote access to the desktop via the RFB
  protocol. Users on remote machines may then connect to the
  desktop using a VNC viewer.
  </description>
  <default>false</default>
</key>
Run Code Online (Sandbox Code Playgroud)

我应该如何使用grep命令来实现这一点?

αғs*_*нιη 12

由于您给定的示例是一个有效的 XML 文件,因此我将使用xqXML 解析器工具作为yq安装包的一部分。

xq -x --xml-root key '
    .schemalist.schema.key[] | select(."@name" == "enabled")
' infile.xml
Run Code Online (Sandbox Code Playgroud)

如果“@name”属性等于“已启用”,则选择“key”标签。

来自xq -h

--xml-output, -x 将
jq JSON 输出转码回 XML 并发出
--xml-root XML_ROOT
转码回 XML 时,将输出封装在具有此名称的元素中


Adm*_*Bee 7

由于您正在处理有效的 XML,您可以使用xmlstarlet

xmlstarlet sel -t -c "/schemalist/schema/key[@name='enabled']" infile.xml
Run Code Online (Sandbox Code Playgroud)

这将查询 ( sel) XML 文档并打印-cXPATH 元素的副本/schemalist/schema/key,其中选择了属性name设置为 的XML 节点enabled

您的示例的输出:

<key name="enabled" type="b">
      <summary>Enable remote access to the desktop</summary>
      <description>
      If true, allows remote access to the desktop via the RFB
      protocol. Users on remote machines may then connect to the
      desktop using a VNC viewer.
      </description>
      <default>false</default>
    </key>
Run Code Online (Sandbox Code Playgroud)


ibu*_*fen 6

要清楚:

这很可能是一些理解 XML 文档的工具的工作,而不是grep类似的工具。对此有很好的答案。


也许:

grep

使用 perl-regexp 和其他补充。

grep -Pzo "(?s)\N*<key name='enabled'.*<\/key>\n" the_file.xml
Run Code Online (Sandbox Code Playgroud)

或者更有限(不捕获前导空格):

grep -zo "<key name='enabled'.*<\/key>."
Run Code Online (Sandbox Code Playgroud)

awk

grep -Pzo "(?s)\N*<key name='enabled'.*<\/key>\n" the_file.xml
Run Code Online (Sandbox Code Playgroud)

或者

grep -zo "<key name='enabled'.*<\/key>."
Run Code Online (Sandbox Code Playgroud)

sed

sed -n '/<key name='\''enabled'\''/,/<\/key>/p' the_file.xml
Run Code Online (Sandbox Code Playgroud)