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

如何用标准CLI工具提取文本中所有# MODE:开头的代码块?

问题描述

我有一个包含随机内容的文件,其中存在多个如下格式的代码块:

# MODE:
bindsym $mod+z mode "$system_mode"
mode "$system_mode" {    
    bindsym Return mode "default"
    bindsym Escape mode "default"
}

foo

# MODE:
bindsym $mod+z mode "$other_mode"
mode "$other_mode" {    
    bindsym blah blah mode "default"
    bindsym foo bar "default"
}

bar

我需要将所有这类代码块提取到另一个文件中。尝试过提取指定模式间内容的sed命令,但只能提取出一个代码块:

sed -e '1,/# MODE:/d' -e '/}/,$d' FILE  

该命令返回单个符合格式的代码块,但我需要提取所有符合要求的代码块。优先采用标准CLI工具方案,也可接受Perl或Python实现。


解决方案

方案1:awk(推荐,简洁高效)

通过状态标记匹配所有目标代码块:

awk '/# MODE:/ {in_block=1; next} in_block {print; if (/^}/) in_block=0}' FILE > output.txt

工作逻辑:

  • 匹配到# MODE:时,开启in_block标记并跳过当前行(不需要输出该行)
  • 标记开启时打印每一行,直到遇到以}开头的行,关闭标记停止打印
  • 结果直接写入output.txt文件

方案2:sed

利用sed的分支循环处理多个块:

sed -n '/# MODE:/{:a;n;p;/^}/!ba}' FILE > output.txt

工作逻辑:

  • -n抑制默认输出,只打印指定内容
  • 匹配到# MODE:后,进入循环a:读取下一行、打印,若该行不是以}开头则重复循环

方案3:Perl

用Perl的逐行处理实现:

perl -ne 'if (/^# MODE:/) {$f=1; next} if ($f) {print; $f=0 if (/^}/)}' FILE > output.txt

工作逻辑:

  • 匹配到# MODE:时开启标记$f,跳过当前行
  • 标记开启时打印行,遇到}时关闭标记

方案4:Python脚本

适合需要自定义逻辑的场景:

with open("FILE", "r") as infile, open("output.txt", "w") as outfile:
    in_block = False
    for line in infile:
        stripped_line = line.strip()
        if stripped_line == "# MODE:":
            in_block = True
            continue
        if in_block:
            outfile.write(line)
            if stripped_line == "}":
                in_block = False

使用方法:
将代码保存为extract_blocks.py,替换FILE为你的目标文件名,运行python extract_blocks.py即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:40:15