【问题标题】:Split Markdown text file by regular expression that defines headings通过定义标题的正则表达式拆分 Markdown 文本文件
【发布时间】:2021-11-01 07:46:42
【问题描述】:

我正在尝试使用命令行程序将较大的文本文件拆分为块:

  • 在定义的正则表达式模式上拆分
  • 由该正则表达式模式中的捕获组定义的文件名

文本文件的格式为:

# Title

# 2020-01-01

Multi-line content
goes here

# 2020-01-02

Other multi-line content
goes here

输出应该是这两个文件,文件名和内容如下:

2020-01-01.md ↓

# 2020-01-01

Multi-line content
goes here

2020-01-02.md ↓

# 2020-01-02

Other multi-line content
goes here

我似乎无法正确掌握所有标准。

拆分(分隔符)的正则表达式模式很简单,类似于^# (2020-.*)$

我无法设置一个多行正则表达式模式,该模式越过\n 换行符并在下一次出现分隔符模式时停止。

或者我可以在正则表达式模式上使用csplit 拆分,但我无法使用(2020-.*) 中捕获的内容命名文件

同样适用于 awk split()match(),无法使其完全正常工作。

我正在寻找一个通用的解决方案,参数是定义块开始(例如# 2020-01-01)和结束(例如下一个日期标题# 2020-01-02EOF)的正则表达式模式

【问题讨论】:

    标签: bash unix awk text-processing unix-text-processing


    【解决方案1】:

    在每个 Unix 机器上的任何 shell 中使用任何 awk:

    $ awk '/^# [0-9]/{ close(out); out=$2".md" } out!=""{print > out}' file
    
    $ head *.md
    ==> 2020-01-01.md <==
    # 2020-01-01
    
    Multi-line content
    goes here
    
    
    ==> 2020-01-02.md <==
    # 2020-01-02
    
    Other multi-line content
    goes here
    

    如果/^# [0-9]/ 不是一个足够的正则表达式,那么将其更改为您喜欢的任何内容,例如/^# [0-9]{4}(-[0-9]{2}){2}$/ 会更严格。 FWIW,尽管如果您没有要求,我根本不会为此使用正则表达式。我会使用:

    awk '($1=="#") && (c++){ close(out); out=$2".md" } out!=""{print > out}' file
    

    【讨论】:

    • 正则表达式试图确保命令可以处理混乱的输入。那里可能还有其他 1 级标题,它们不是日期、错别字、带有 # 作为 cmets 的围栏代码块。该文件有 331 个这样的标题,但命令输出 327 个文件
    • 通过差异发现,不匹配是由于重复的日期戳,因此文件会被覆盖。我想这个解决方案可以解决这个问题,但我只是编辑源文档来纠正它。
    • 当发现重复的日期时,很容易附加到文件而不是覆盖它,或者在重复的文件名后附加“.1”或其他内容。如果您想要任何这些,请告诉我,我会更新答案。
    【解决方案2】:

    使用this regex,这里有一个perl来做到这一点:

    perl -0777 -nE 'while (/^\h*#\h*(2020.*)([\s\S]*?(?:(?=(^\h*#\h*2020.*))|\z))/gm) {
        open($fh, ">", $1.".md") or die $!;
        print $fh $1;
        print $fh $2;
        close $fh;
    }' file 
    

    结果:

    head 2020*
    ==> 2020-01-01.md <==
    2020-01-01
    
    Multi-line content
    goes here
    
    
    ==> 2020-01-02.md <==
    2020-01-02
    
    Other multi-line content
    goes here
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-31
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多