我有许多 Markdown 文件,顶部有一个 YAML 元数据块:
---
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
---
**title**
a piece of indertimate
length that could be a few lines of many hundreds
---[author name](author link)
---found in [source](source link)
我正在尝试找到一种提取元数据块的方法(这样我可以将其输入到yamllint
,但后来也可以输入其他内容)。 awk 似乎是正确的工具,但是当我不理解 awk 时,我想出的最好的方法是:
awk '/^---$/ {printline = 1; print; next} /^---$/ {printline = 0} printline'
这只是显示了整个文件,我尝试限制---
它们自己的行是行不通的(也许这里没有其他的)!
答案1
sed
可能是更好的工具选择。由于它始终位于文件的顶部,因此您可以指定sed
只打印从第 2 行到该---
行的内容,然后删除该行。
例如
sed -n '2,/^---$/ {/^---$/d; p}'
这是通过以下方式实现的:
-n: don't print by default
2,/^---$/ { ... }: limit the next part to the lines between line 2 and the first line matching ---
然后在那个街区内
/^----$/d : delete the --- line
p : print what remains.
所以在你的测试文件中输出是
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
要做到这一点awk
需要跟踪状态。例如
awk '
/^---$/ && printline==0 {printline = 1;next}
/^---$/ {printline = 2; next}
{ if (printline==1) { print } }
'
---
如果文件的其余部分中有一行,则需要此状态。
答案2
由于元数据块是由---
分隔符分隔的,因此我们可以将记录分隔符/设置RS
为此。
假设元数据块始终位于 yaml 文件的开头并用 分隔---
,则可以安全地假设第二条记录将是元数据块,因此我们可以说:
➜ awk 'BEGIN { RS = "---" } NR==2' example-yaml.txt
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
来提取它。
awk
默认使用换行符作为记录分隔符,但是(至少在 GNU awk 中,其他 awk 实现可能有所不同,因为我除了 gawk 之外还没有验证这一点)它可以设置为任何/多个字符以及正则表达式(请参阅awk 分割记录(GNU Awk 用户指南)以供参考)。
答案3
使用编辑编辑器删除从第二个 YAML 文档分隔---
符到文档末尾的所有内容,然后显示剩余内容:
$ printf '%s\n' '1;/^---$/,$d' ,p Q | ed -s file
---
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
反转所有行,删除第一个---
分隔符(这将是 YAML 部分末尾的分隔符),然后再次反转行:
$ tail -r file | sed '1,/^---$/d' | tail -r
---
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
答案4
和awk:
$ awk 'BEGIN{printline=2} /^---$/{printline--; next} printline' file.yaml
title: title of work
author: author name
author-sort: name, author
published: N
date: XXXX-XX-XX
pub-number: XXXXX
embedded-title: false
printline
命令末尾是一种打印语句,就正awk
整数的默认行为是打印整行。一开始,该printline
变量设置为 2,然后每次正则表达式^---$
匹配时递减。所以当printline
为零时,awk
停止打印。