如何从降价文件中删除 YAML frontmatter?

How to remove YAML frontmatter from markdown files?

我有包含 YAML frontmatter 元数据的降价文件,如下所示:

---
title: Something Somethingelse
author: Somebody Sometheson 
---

但是 YAML 的宽度不同。我可以使用像 sed 这样的 Posix 命令来删除位于文件开头的 frontmatter 吗?只是删除 ------ 之间的所有内容,包括在内,但也会忽略文件的其余部分,以防其他地方有 ---

如果您不介意 "or something" 是 perl。

找到两个“---”实例后简单地打印:

perl -ne 'if ($i > 1) { print } else { /^---/ && $i++ }' yaml

如果您不介意滥用 ?: 用于流量控制,或者更短一些:

perl -ne '$i > 1 ? print : /^---/ && $i++' yaml

如果要替换内联,请务必包含 -i

我理解你的问题的意思是你想删除第一个 --- 封闭的块,如果它从第一行开始的话。那样的话,

sed '1 { /^---/ { :a N; /\n---/! ba; d} }' filename

这是:

1 {              # in the first line
  /^---/ {       # if it starts with ---
    :a           # jump label for looping
    N            # fetch the next line, append to pattern space
    /\n---/! ba; # if the result does not contain \n--- (that is, if the last
                 # fetched line does not begin with ---), go back to :a
    d            # then delete the whole thing.
  }
}
                 # otherwise drop off the end here and do the default (print
                 # the line)

根据您希望如何处理以 ---abc 左右开头的行,您可能需要稍微更改模式(也许在末尾添加 $ 以仅在整个行是 ---)。我不太清楚你那里的具体要求。

如果你只想删除前面的内容,你可以简单地 运行:

sed '1{/^---$/!q;};1,/^---$/d' infile

如果第一行不匹配---sedq退出;否则它将 d删除从第 1 行到(并包括)与 --- 匹配的下一行(即整个前面的内容)的所有内容。

您使用 bash 文件,创建 script.sh 并使用 chmod +x script.sh 和 运行 使其可执行 ./script.sh.

#!/bin/bash

#folder articles contains a lot of markdown files
files=./articles/*.md

for f in $files;
do
    #filename
    echo "${f##*/}"
    #replace frontmatter title attribute to "title"
    sed -i -r 's/^title: (.*)$/title: ""/' $f
    #...
done

这个基于 AWK 的解决方案适用于有和没有 FrontMatter 的文件,在后一种情况下什么都不做。

#!/bin/sh
# Strips YAML FrontMattter from a file (usually Markdown).

# Exit immediately on each error and unset variable;
# see: https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -Ee

print_help() {
    echo "Strips YAML FrontMattter from a file (usually Markdown)."
    echo
    echo "Usage:"
    echo "    `basename [=10=]` -h"
    echo "    `basename [=10=]` --help"
    echo "    `basename [=10=]` -i <file-with-front-matter>"
    echo "    `basename [=10=]` --in-place <file-with-front-matter>"
    echo "    `basename [=10=]` <file-with-front-matter> <file-to-be-without-front-matter>"
}

replace=false
in_file="-"
out_file="/dev/stdout"

if [ -n "" ]
then
    if [ "" = "-h" ] || [ "" = "--help" ]
    then
        print_help
        exit 0
    elif [ "" = "-i" ] || [ "" = "--in-place" ]
    then
        replace=true
        in_file=""
        out_file="$in_file"
    else
        in_file=""
        if [ -n "" ]
        then
            out_file=""
        fi
    fi
fi

tmp_out_file="$out_file"
if $replace
then
    tmp_out_file="${in_file}_tmp"
fi

awk -e '
BEGIN {
    is_first_line=1;
    in_fm=0;
}
/^---$/ {
    if (is_first_line) {
        in_fm=1;
    }
}
{
    if (! in_fm) {
        print [=10=];
    }
}
/^(---|...)$/ {
    if (! is_first_line) {
        in_fm=0;
    }
    is_first_line=0;
}
' "$in_file" >> "$tmp_out_file"

if $replace
then
    mv "$tmp_out_file" "$out_file"
fi