unix 仅在与grep匹配的多行模式中匹配第一个命中

x759pob2  于 2023-04-29  发布在  Unix
关注(0)|答案(1)|浏览(144)

假设我有下面简化类型的XML文件,并且需要提取<innerElement></innerElement>标记中的所有字符串数据,仅用于Id 1234。

<outerTag>
  <innerElement>
    <Id>1234</Id>
    <fName>Kim</fName>
    <lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
    <position>North</position>
    <title/>
  </innerElement>
  <innerElement>
    <Id>5678</Id>
    <fName>Brian</fName>
    <lName>Davis</lName>
<customData3>value3</customData3>
<customData4>value4</customData4>
<customData5>value5</customData5>
    <position>South</position>
    <title/>
  </innerElement>
</outerTag>

我的预期输出是:

<innerElement>
    <Id>1234</Id>
    <fName>Kim</fName>
    <lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
    <position>North</position>
    <title/>
</innerElement>

根据我在其他文章中读到的内容,我尝试使用grep -z来匹配多行字符串(将文件内容视为一行),使用-o只打印精确匹配的字符串,但是当我使用。* 在Id元素之后的通配符,它结束匹配所有内容直到文件的结尾,而不是在第一次出现时停止。
grep -zo '<innerElement>.*<Id>1234</Id>.*</innerElement>' myfile.xml
如何使模式只匹配第一次出现的内容或ID 1234之后的标记?

0wi1tuuw

0wi1tuuw1#

Don't use sed nor regex to parse XML您不能,也不能使用设计用于处理原始文本行的工具来解析任何结构化文本(如XML/HTML)。如果需要处理XML/HTML,请使用XML/HTML解析器。绝大多数语言都内置了对XML解析的支持,如果您需要从命令行shell快速获取,可以使用xidelxmlstarletxmllint等专用工具。

使用正确的XML解析器

使用xidel
xidel --xml -e '//innerElement[Id="1234"]' file.xml
使用xmlstarlet
xmlstarlet sel -t -c '//innerElement[Id="1234"]' file.xml
使用xmllint
xmllint --xpath '//innerElement[Id="1234"]' file.xml
输出
<innerElement>
    <Id>1234</Id>
    <fName>Kim</fName>
    <lName>Scott</lName>
    <customData1>Value1</customData1>
    <customData2>Value2</customData2>
    <position>North<position><title/></position>
  </position>
  </innerElement>

相关问题