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

GNU AWK如何优雅提取两模式间文本且不包含模式本身

GNU AWK单命令提取指定标签区间文本方案

运行环境

GNU AWK 5.1.1

需求说明

仅使用AWK(不调用SED)完成以下处理:

  • 提取.txt文档中<monDescription>与<endMonDescription>两个标签之间的全部文本
  • 输出不包含标签本身
  • 去除标签所在行前缀的「DAVE: 」无关内容
  • 规整多余空白,输出干净的区间文本

原有方案问题

直接使用基础区间匹配命令,输出会包含两个目标标签,不符合要求:

awk '/<monDescription>/,/<endMonDescription>/' ~mydocument.txt

现有三段AWK管道拼接的实现虽然能得到正确结果,但管道冗余、执行效率低、写法不够优雅:

awk '/<monDescription>/,/<endMonDescription>/' ~mydocument.txt | awk '{gsub(/<monDescription>|<endMonDescription>|DAVE:/, "")}1' | awk '{$1=$1;print}'

输入样例

DAVE:   <monDescription>Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
sociis natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu,
pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo,
fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo,
rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis
eu pede mollis pretium.<endMonDescription>

单AWK实现命令

awk '
match($0, /<monDescription>(.*)/, m) {
    in_block = 1
    $0 = m[1]
}
in_block {
    if (match($0, /(.*)<endMonDescription>/, m)) {
        $0 = m[1]
        end_hit = 1
    }
    sub(/^[[:space:]]*DAVE:[[:space:]]*/, "")
    content = content " " $0
    if (end_hit) {
        gsub(/^[[:space:]]+|[[:space:]]+$/, "", content)
        gsub(/[[:space:]]+/, " ", content)
        print content
        exit
    }
}
' ~mydocument.txt

逻辑说明

  • 通过in_block变量标记是否进入目标文本区间,匹配到起始标签时开启标记,同时截除起始标签及标签前的所有内容
  • 区间内逐行将内容拼接到缓存变量content,匹配到结束标签时截除结束标签及标签后的所有内容,标记准备输出
  • 自动清理行首可能残留的DAVE: 前缀及附属空白
  • 匹配到结束标签后统一规整所有空白:合并连续空白为单个空格、去除首尾多余空白,输出结果后直接退出进程,减少不必要的文件扫描
    针对上述输入样例,命令会输出规整后的纯文本,无标签、无无关前缀、无多余空白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:48:47