無効なYAMLヘッダーを見つける

無効なYAMLヘッダーを見つける

私のプロジェクトのどのファイルに間違ったヘッダーがあるかを確認しようとしています。ファイルはすべて次のように始まります。

---
header:
.
.
.
title: 
some header:
.
.
.
more headers:
level: 
.
.
.
---

どこ。 。 。より多くのヘッダーを意味します。タイトルにインデントは含まれていません。次の式を使用すると、各ファイルからYAMLヘッダーを抽出できます。

grep -Przo --include=\*.md "^---(.|\n)*?---" .

今、私は間違ったYAMLヘッダーをリストしたいと思います。

  • 各YAMLヘッダーにtitle: some text
  • 各YAMLヘッダーには以下が必要です。language: [a-z]{2}
  • external: .*またはを含める必要がありますauthor: .*
  • title:level:、 の位置external:language:さまざまです。

私は次のようなことをしようとします。

grep -L --include=\*.md -e "external: .*" -e "author: .* ."

しかし、問題は、YAMLヘッダーだけでなくファイル全体を検索することです。したがって、上記の問題に対する解決策は、以前に検索したYAMLヘッダーの結果を再びgrepに供給する方法に依存していると思います。頑張った

grep -Przo --include=\*.md "^---(.|\n)*?---" . | xargs -0 grep "title:";

しかし、これを行うと、「該当するファイルやディレクトリがありません」というエラーが発生するため、どのように進むべきかわかりません。

例:

---
title: Rull-en-ball
level: 1
author: Transkribert og oversatt fra [Unity3D](http://unity3d.com)
translator: Bjørn Fjukstad
license: Oversatt fra [unity3d.com](https://unity3d.com/learn/tutorials/projects/roll-ball-tutorial)
language: nb
---

作成者、言語、タイトルを含むYAMLを編集してください。

---
title: Mini Golf
level: 2
language: en
external: http://appinventor.mit.edu/explore/ai2/minigolf.html
---

作成者の代わりにタイトル、言語、外部を使用してYAMLを編集してください。

---
title: 'Stjerner og galakser'
level: 2
logo: ../../assets/img/ccuk_logo.png
license: '[Code Club World Limited Terms of Service](https://github.com/CodeClub/scratch-curriculum/blob/master/LICENSE.md)'
translator: 'Ole Andreas Ramsdal'
language: nb
---

無効なYAMLヘッダー、著者の欠落。

ベストアンサー1

これは一つの方法です。私はあなたがbash(再帰的にファイルを繰り返す)、sedとawkを持っていると仮定します。 bashを使用する代わりにfindwithを使用-execしてファイルを検索することもできます。

一般的なプロセスは次のとおりです。

  1. *.mdbashにファイルリストを再帰的に要求する
  2. 各ファイルを渡してsedYAMLヘッダーを抽出する
  3. 検証のために、このYAMLヘッダーをawkに渡してください。
  4. ヘッダーの検証に失敗した場合は、ファイル名を印刷します。

スクリプト:

#!/bin/bash
shopt -s globstar

for file in **/*.md
do
  # use sed for the header
  sed -n /^---$/,/^---$/p "$file" |
  awk '
        BEGIN {
                good_title=0
                good_lang=0
                good_extaut=0
        }
        /^title: .*/             { good_title=1  }
        /^language: [a-z][a-z]$/ { good_lang=1   }
        /^author: .*/            { good_extaut=1 }
        /^external: .*/          { good_extaut=1 }
        END {
                if (good_title && good_lang && good_extaut)
                        exit 0
                else
                        exit 1
        }
        '  \
  || printf "Incorrect header found in %s\n" "$file"
done

.特定の要件に応じて、awkスクリプトの正規表現一致パターンをより厳密または緩やかに簡単に調整できます(例の現在の文字のように、「any」ではなく英数字が必要になる場合があります)。

このsedステートメントは、次のようにYAMLヘッダーを抽出します。

  • デフォルト印刷を無効にする(-n
  • 次のパターンに一致する行のアドレスを要求します。行の始まり、行の終わり---2番目のパターンは最初のパターンの後に表示する必要があります。
  • p次に、対応するアドレス範囲を印刷します。

スクリプトawkは少し過度に構成されていますが、明確にするために説明します。 awkが呼び出されるたびに、3つのフラグ変数を0またはfalseに設定します。基準を満たす行がある場合は、そのフラグを1 / trueに設定します。すべての行が確認されると、これらのフラグの状態に基づいて成功または失敗を返します。検証を「通過」するには、すべてtrueでなければなりません。

適切に名前が付けられたサンプルファイルを現在のディレクトリとサブディレクトリに分散します。

$ tree .
.
├── bad1.md
├── good1.md
├── good2.md
└── subdir
    ├── bad1.md
    └── good1.md

1 directory, 5 files

...スクリプト出力:

Incorrect header found in bad1.md
Incorrect header found in subdir/bad1.md

おすすめ記事