【问题标题】:How to Return Everything After 2nd Occurance of String如何在第二次出现字符串后返回所有内容
【发布时间】:2017-01-30 18:15:55
【问题描述】:

我想知道在第二次出现字符串之后获取所有内容的最佳方法是什么。我有这样的文件:

---
title: Test Document
creation_date: 01-29-2016
---

Text, blah blah blah
More text, blah blah blah

所以我有两个---s 之间包含“frontmatter”的文件。我想在第二个--- 之后返回所有内容,最好使用某种 bash 命令。想到这里,我想到了 sed 和 awk,但我真的不知道哪个更适合这项工作。

其中一个重要的部分是,frontmatter 中可以有任意数量的键值对,因此在这里仅删除前四行不是有效的方法。

【问题讨论】:

  • 最好用精确的输入来解释你有想要的精确输出。
  • 如果您真的打算进行大量自动查询,则需要使用不同的文件格式。这看起来像是为人眼快速扫描而设计的,而不是程序解析。
  • 当您试图确定是否应该使用 sed 或 awk 来解决任何问题时:sed 用于在单个行上进行简单替换(仅此而已),awk 用于其他所有问题.您描述的问题不是对单个行的简单替换,因此它不是 sed 的工作,而是 awk 的工作。如果您尝试将 sed 用于其他任何事情,您很快就会发现自己陷入了难以理解的符文、可移植性问题、效率低下以及几乎所有其他不良软件属性的地狱。

标签: bash awk sed text-processing


【解决方案1】:

使用 awk 你可以做到这一点:

awk 'p>1; /---/{++p}' file

Text, blah blah blah
More text, blah blah blah

【讨论】:

    【解决方案2】:

    使用 sed,您可以删除两个模式之间的一系列线条:

    sed '/---/,/---/d' file
    

    其他行自动显示。

    More about sed features.

    如果你也想删除上面的行,你可以使用这个:

    sed '1{:a;N;/---.*---/d;ba}' file
    

    详情:

    1  # if the current line is the first one
    {
        :a  # define a label "a"
        N   # append the next line to the pattern space
        /---.*---/d  # delete the pattern space when the pattern succeeds
        ba  # go to label "a"
    }
    

    请注意,d 命令会无条件地停止脚本,而 sed 会继续执行剩余的行。

    【讨论】:

    • 这将打印第一个---上方的行;不清楚这是否是 OP 的问题...
    • @dawg:我已经添加了另一个版本来做到这一点。
    • sed -rn '1{ :X /---/{ H; G; /---\n---/d }; n; bX }; p'文件
    【解决方案3】:

    这是一个纯 Bash 解决方案:

    while IFS= read -r line || [[ -n $line ]]; do 
        if [[ "$line" =~ ^--- ]]; then
            (( ++count ))
        elif [ $count -ge 2 ]; then
            echo "$line"
        fi
    done <file
    

    您可以以类似 sed 的方式使用 awk 来打印该模式匹配范围之外的所有内容,如下所示:

    awk '/^---/,/^---/ {next} 1' file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2013-03-02
      • 2011-05-19
      • 2015-09-19
      • 2022-08-24
      • 2015-05-04
      • 1970-01-01
      相关资源
      最近更新 更多