【发布时间】:2021-01-30 23:01:26
【问题描述】:
我想使用sed 或awk 替换特定的xml 节点值。我不能使用专门的包来解析 xml,例如 xmlstarlet、xmllint 等。我必须使用 sed 或 awk strong>,只是“基本”外壳。
我有很多大的 xml 文件。在该文件中,我想定位并替换两个标签值:示例:
<desc:partNumber>>2</desc:partNumber>
<desc:dateIssued>>1870</desc:dateIssued>
问题是,这些名称有数百个标签。但这两个标签的父标签在整个 xml 文件中是唯一的:
<desc:desc ID="DESC_VOLUME_0001">
另一个问题是每个文件中父 <desc:desc ID="DESC_VOLUME_0001"> 内的标签 <desc:partNumber> 和 <desc:dateIssued> 的位置或行号是不同的。
我认为解决方案是:
- 定位并提取父级
<desc:desc ID="DESC_VOLUME_0001">及其子级到变量 - 迭代子节点并获取
<desc:partNumber>的位置(行号) 和<desc:dateIssued>并保存到变量 - 将行号传递给
sed命令并替换当前值 具有新值的标签(将从 .csv 文件中读取新值)
我尝试创建这个sed 命令,你可以看到我使用'n' 来移动行,但这需要是可变的。
sed -i '/desc:desc ID="DESC_VOLUME_0001"/{n;n;n;n;n;n;n;n;n;s/'"${OLD_DATE_ISSUED}"'/'"${NEW_DATE_ISSUED}"'/}'
有子节点的父节点:
<desc:desc ID="DESC_VOLUME_0001">
<desc:physicalDescription>
<desc:note>text</desc:note>
</desc:physicalDescription>
<desc:titleInfo>
<desc:partNumber>2</desc:partNumber>
</desc:titleInfo>
<desc:originInfo>
<desc:dateIssued>1870</desc:dateIssued>
</desc:originInfo>
<desc:identifier type="uuid">81e32d30-6388-11e6-8336-005056827e52</desc:identifier>
</desc:desc>
任何人都可以帮助如何实现这一目标?
【问题讨论】:
-
请在您的问题中添加示例输入(无描述、无图像、无链接)以及该示例输入所需的输出(无评论)。
-
不能使用专门的包来解析 xml,如 xmlstarlet、xmllint 等。 你应该告诉做出这个决定的人,他们在给你下跪。使用 XML 感知工具是稳健有效地执行此操作的唯一方法。
-
为什么不使用单独的 sed 替换打开和关闭标签?并且请注意尖括号,以免您也意外替换 desc:partNumberClient。
-
"我必须使用 sed 或 awk,只是“基本”外壳。"不,你没有。这是工作的错误工具。您的代码将不正确且效率低下。
-
相关:bobince 对RegEx match open tags except XHTML self-contained tags 的警示性回答
标签: xml bash awk sed xml-parsing