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

Bash中指定标题下Quote与Note的提取及格式化优化问题

问题描述

我正在处理一个结构如下的文件:

Title1
- Quote

this is a quote
==========
Title1
- Note

this is a note
==========
Title1
- Quote

this is another quote
==========
Title1
- Note

this is another note

每个标题(如Title1、Title2等)包含数百条Quote,其中部分Quote后跟随对应的Note。每条Quote和Note内容各不相同,但标识- Quote和- Note在文件中固定不变,且每条具体的Quote和Note均为单行。

针对指定标题,我希望按如下格式显示Quote内容及对应的Note内容:

this is a quote
   >> this is a note
--
this is another quote
   >> this is another note

我尝试使用命令:

grep -C 6 "Title1" | grep -B 3 -A 2 "Note" | egrep -v "Title1|=====|Note"

得到的结果如下:

this is a quote

this is a note
--
this is another quote

this is another note

请问如何调整格式以达到预期效果?同时我是Bash新手,想了解是否有更高效的实现方式(曾尝试sed但未成功),恳请提供帮助!


解决方案

一、调整现有grep命令的格式

你的现有命令已经提取出了对应内容,只需添加格式处理步骤即可:

grep -C 6 "Title1" | grep -B 3 -A 2 "Note" | egrep -v "Title1|=====|Note" | sed '/^$/d; N; s/\n/   >> /; a\--' | sed '$d'

分步解释:

  1. sed '/^$/d':删除所有空行
  2. N:将下一行内容追加到当前行的缓冲区
  3. s/\n/ >> /:把换行符替换成 >>,实现预期的缩进格式
  4. a\--:在每组Quote-Note后添加分隔线--
  5. sed '$d':删除最后一行多余的--

二、更高效的awk实现(推荐)

awk适合处理这种有逻辑关联的文本,只需遍历文件一次,效率更高:

awk -v target="Title1" '
    /^==========$/ { in_title=0 }
    $0 == target { in_title=1 }
    in_title && /^- Quote$/ { getline; quote=$0 }
    in_title && /^- Note$/ { getline; print quote "\n   >> " $0 "\n--" }
' your_file.txt | sed '$d'

分步解释:

  1. -v target="Title1":定义要匹配的标题变量,后续修改只需改这里
  2. /^==========$/ { in_title=0 }:遇到分隔线时,标记退出目标标题块
  3. $0 == target { in_title=1 }:匹配到目标标题时,标记进入目标标题块
  4. in_title && /^- Quote$/ { getline; quote=$0 }:在目标块内,遇到- Quote时读取下一行,保存为Quote内容
  5. in_title && /^- Note$/ { getline; print quote "\n >> " $0 "\n--" }:在目标块内,遇到- Note时读取下一行,按预期格式输出Quote和Note,并添加分隔线
  6. sed '$d':删除最后一行多余的--

三、sed实现方案

如果想尝试sed,可用以下命令:

sed -n '/^Title1$/,/^==========$/{
    /^- Quote$/{n;h}
    /^- Note$/{n;H;g;s/\n/   >> /;p;s/.*//;a\--}
}' your_file.txt | sed '$d'

分步解释:

  1. -n '/^Title1$/,/^==========$/{...}':仅处理Title1到分隔线之间的内容
  2. /^- Quote$/{n;h}:遇到- Quote时,读取下一行并保存到临时缓存区
  3. /^- Note$/{n;H;g;s/\n/ >> /;p;s/.*//;a\--}:遇到- Note时,读取下一行追加到缓存区,合并后替换换行符为格式串,打印结果并添加分隔线
  4. sed '$d':删除最后一行多余的--

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:25:16