You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将XML item块中提取的日期插入对应块的每一行?

问题描述

我有如下XML格式的item文本块:

<item>
    <link>test1</link>
    <title>ABC1</title>
    <Date>Tue, 07 Jun 2023</Date>
</item>
<item>
    <link>test3</link>
    <title>ABC3</title>
    <Date>Fri, 27 Jun 2022</Date>
</item>
<item>
    <link>test2</link>
    <title>ABC2</title>
    <Date>Mon, 05 Jun 2021</Date>
</item>

期望转换为如下格式:

Tue, 07 Jun 2023 <item> 
Tue, 07 Jun 2023     <link>test1</link>
Tue, 07 Jun 2023     <title>ABC1</title>
Tue, 07 Jun 2023     <Date>Tue, 07 Jun 2023</Date>
Tue, 07 Jun 2023 </item>
Fri, 27 Jun 2022 <item>
Fri, 27 Jun 2022     <link>test3</link>
Fri, 27 Jun 2022     <title>ABC3</title>
Fri, 27 Jun 2022     <Date>Fri, 27 Jun 2022</Date>
Fri, 27 Jun 2022 </item>
Mon, 05 Jun 2021 <item>
Mon, 05 Jun 2021     <link>test2</link>
Mon, 05 Jun 2021     <title>ABC2</title>
Mon, 05 Jun 2021     <Date>Mon, 05 Jun 2021</Date>
Mon, 05 Jun 2021 </item>

我已经能用以下grep命令提取日期:

grep -oE "[A-Z][a-z][a-z],.*2[0-9][0-9][0-9]" ./file

但不知道如何将提取的日期插入到对应<item>至</item>文本块的每一行开头,需要按块处理文本,求解决思路。

解决思路与实现

核心是按<item>块分组,提取每个块内的日期后,给块内每一行前缀加上该日期。用awk可以高效完成这个需求,无需拆分文件再合并:

awk '
/<item>/ {
    in_item = 1
    block_lines = ""
    next
}
in_item && /<Date>(.*)<\/Date>/ {
    date = gensub(/.*<Date>(.*)<\/Date>.*/, "\\1", "g", $0)
}
in_item {
    block_lines = block_lines $0 "\n"
    if (/<\/item>/) {
        n = split(block_lines, lines, "\n")
        for (i=1; i<=n; i++) {
            if (lines[i] != "") {
                print date " " lines[i]
            }
        }
        in_item = 0
        date = ""
    }
}
' ./file

命令解释

  1. 遇到<item>时,标记进入块模式,初始化存储块内容的变量。
  2. 在块内匹配<Date>行,用gensub提取纯日期文本。
  3. 持续累加块内所有行,直到遇到</item>时,遍历块内每一行,拼接日期后输出。
  4. 退出块模式,重置变量以处理下一个item块。

如果需要直接修改原文件,部分awk版本支持-i inplace参数实现原地编辑:

awk -i inplace '
# 同上脚本内容
' ./file

内容的提问来源于stack exchange,提问作者KarlsD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:47:26