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이 줄부터 두 번째 줄만 ---인쇄되도록 지정한 다음 해당 줄을 삭제할 수 있습니다.

예를 들어

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에서는 gawk 이외의 것을 확인하지 않았기 때문에 다른 awk 구현은 다를 수 있습니다) 정규식뿐만 아니라 임의/여러 문자로 설정할 수 있습니다( 보다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

구현하는 경우옵션이 없습니다 -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인쇄를 중지합니다.

관련 정보