Aqui está uma maneira de fazer isso. Eu suponho que você tem bash (para loop recursivamente através dos arquivos), sed e awk. Em vez de usar o bash, você poderia alternativamente usar find
com -exec
para procurar pelos arquivos.
O fluxo geral é:
- pergunte ao bash pela lista de
*.md
arquivos, recursivamente - passa cada arquivo para
sed
para extrair o cabeçalho YAML - transmita esse cabeçalho YAML para awk para validação
- se o cabeçalho falhar na validação, imprima o nome do arquivo
O script:
#!/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
Você pode facilmente ajustar os padrões de correspondência regex no script awk para serem mais rígidos ou mais soltos, dependendo de suas necessidades exatas (talvez você queira caracteres alfanuméricos em vez de "any", como o atual .
em seu exemplo possui).
A instrução sed
extrai o cabeçalho YAML por:
- suprimindo a impressão padrão (
-n
) - pedindo uma linha de endereços que corresponda ao padrão: início da linha,
---
, fim da linha; o segundo padrão deve ocorrer após o primeiro padrão. - esse intervalo de endereços é então
p
rinted
O script awk
é um pouco over-built, mas eu queria soletrar para maior clareza. Cada vez que awk é chamado, ele define três variáveis de sinalização como zero ou falso. Se virmos linhas que correspondem aos nossos critérios, definimos o sinalizador correspondente como um / verdadeiro. Uma vez que todas as linhas tenham sido vistas, retornamos sucesso ou falha com base no status dessas flags - elas devem ser todas verdadeiras para "passar" a validação.
Com esses arquivos de amostra adequadamente nomeados espalhados no diretório atual e em um subdiretório:
$ tree .
.
├── bad1.md
├── good1.md
├── good2.md
└── subdir
├── bad1.md
└── good1.md
1 directory, 5 files
... o script mostra:
Incorrect header found in bad1.md
Incorrect header found in subdir/bad1.md