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'
分步解释:
sed '/^$/d':删除所有空行N:将下一行内容追加到当前行的缓冲区s/\n/ >> /:把换行符替换成>>,实现预期的缩进格式a\--:在每组Quote-Note后添加分隔线--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'
分步解释:
-v target="Title1":定义要匹配的标题变量,后续修改只需改这里/^==========$/ { in_title=0 }:遇到分隔线时,标记退出目标标题块$0 == target { in_title=1 }:匹配到目标标题时,标记进入目标标题块in_title && /^- Quote$/ { getline; quote=$0 }:在目标块内,遇到- Quote时读取下一行,保存为Quote内容in_title && /^- Note$/ { getline; print quote "\n >> " $0 "\n--" }:在目标块内,遇到- Note时读取下一行,按预期格式输出Quote和Note,并添加分隔线sed '$d':删除最后一行多余的--
三、sed实现方案
如果想尝试sed,可用以下命令:
sed -n '/^Title1$/,/^==========$/{ /^- Quote$/{n;h} /^- Note$/{n;H;g;s/\n/ >> /;p;s/.*//;a\--} }' your_file.txt | sed '$d'
分步解释:
-n '/^Title1$/,/^==========$/{...}':仅处理Title1到分隔线之间的内容/^- Quote$/{n;h}:遇到- Quote时,读取下一行并保存到临时缓存区/^- Note$/{n;H;g;s/\n/ >> /;p;s/.*//;a\--}:遇到- Note时,读取下一行追加到缓存区,合并后替换换行符为格式串,打印结果并添加分隔线sed '$d':删除最后一行多余的--
内容的提问来源于stack exchange,提问作者nobloat
相关产品推荐
相关产品推荐

