awkを使用してYAMLメタデータチャンクを抽出する方法

awkを使用してYAMLメタデータチャンクを抽出する方法

上部にはYAMLメタデータブロックを含むMarkdownファイルがいくつかあります。

---
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ファイルの先頭にあり、で区切られていると仮定すると、---2番目のレコードがメタデータチャンクになると仮定するのが安全なので、次のように言えます。

➜ 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ではgawk以外のものを確認していないため、他のawk実装は異なる場合があります)正規表現だけでなく、任意/複数文字に設定できますawk分割レコード(GNU Awkユーザーガイド)参考用)。

答え3

使用エディターは、---2 番目の 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

実装する場合オプションはありません-r(macOSや他のBSDシステムで利用可能)。 GNUを使用できます。代わりに。

答え4

そして:

$ 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に設定され、正規表現が^---$一致するたびに減少します。したがって、printline0になるとawk印刷を停止します。

関連情報