GNU sed를 사용하여 빈 줄로 구분될 수 있는 두 패턴 줄 사이의 헤더 이름 추출

GNU sed를 사용하여 빈 줄로 구분될 수 있는 두 패턴 줄 사이의 헤더 이름 추출

다음 파일이 있습니다.

------

Introduction
----------
Optio eum enim ut. Et quia molestias eos. Doloribus laborum quia quae. Magnam cupiditate quis consectetur.

-----
Chapter1: Foo
-----

Odit beatae eius voluptas temporibus sint quia. Eos et tempora similique laboriosam optio consequatur quibusdam. Fugit suscipit cupiditate ea perspiciatis rem labore cum eos.

-----
Chapter bar


-----
Et consequatur quia quia et architecto et sunt. Perferendis qui deserunt qui est illo est sapiente ipsam. Fugiat vel amet magni in quam. Eligendi totam cum sapiente harum blanditiis minima

다음과 같은 제약 조건이 있습니다.

  • 제목 기호는 -최소 5자 이상이어야 합니다.
  • -헤더와 헤더 사이에는 원하는 수의 빈 줄이 있을 수 있습니다(그러나 제한됨).

예상되는 출력은 다음과 같습니다.

Introduction
Chapter1: Foo
Chapter bar

를 사용하여 이 작업을 수행할 수 있다는 것을 알고 있지만 awk제안하지 마십시오. 나는 순수한 GNU sed 솔루션을 보고 싶습니다.

지금까지 시도한 내용은 다음과 같습니다.

sed -n ':a; /-\+/{n; /^$/!{p; b a}}' input.txt

그러나 명령이 작동하지 않는 것 같습니다.

답변1

이렇게 하면 헤더 내에 있는 한 하나 이상의 영문자 또는 숫자가 포함된 줄이 인쇄됩니다.

sed -n '/^-----/,/^-----/{/[[:alnum:]]/p;}' file

답변2

나는 이 솔루션을 제안합니다:

$ sed -n '/\-\{5,\}/,/\-\{5,\}/p' file | sed '/\-\+\|^$/d'
Introduction
Chapter1: Foo
Chapter bar

  • '/\-\{5,\}/,/\-\{5,\}/p'섹션 중에서 선택합니다 -(최소 5개).
  • '/\-\+\|^$/d'빈 줄을 제거하거나 로 끝납니다 -.

답변3

sed실제로 다른 도구에서도 이 작업을 수행 할 수 있지만일이 더 쉬워질 것입니다(IMO)1 도 작동합니다. 예를 들면 다음과 같습니다 awk.

$ awk '/-----/ && !a{a=1;next} /-----/ && a{a=0}a' file 

Introduction
Chapter1: Foo
Chapter bar


빈 줄을 제거하려면 다음을 수행하십시오.

$ grep . file | awk '/-----/ && !a{a=1;next} /-----/ && a{a=0}a'
Introduction
Chapter1: Foo
Chapter bar

또는:

$ awk '!/./{next};/-----/ && !a{a=1;next} /-----/ && a{a=0}a' file 
Introduction
Chapter1: Foo
Chapter bar

여기서의 아이디어는 변수가 현재 0이거나 설정되지 않은 경우( a) 현재 행이 5 이상과 일치하면 변수를 설정한다는 것입니다. 1로 설정된 경우 5를 포함하는 다른 행을 찾으면 다시 로 설정됩니다. 그런 다음 설정된 모든 행을 인쇄합니다(이것이 final이 수행하는 작업입니다. 0이 아닌 것으로 평가되면 인쇄됩니다).1!a-0-aaaa

다음은 보다 이해하기 쉬운 방식으로 작성된 동일한 내용입니다.

awk '{ 
        if(!/./){ next } 
        if(/-----/ && !a){ a=1; next} 
        if(/-----/ && a){ a=0 } 
        if(a){ print }
    }' file

1콰지모도의 답변훨씬 더 간단합니다!

답변4

당신은 그것을 사용할 수 있습니다 :

sed -n '/^-\+$/,/^-\+$/{/^-*$/!p}' input.txt

또는 다음을 사용할 수 있습니다 sed -z.

sed -Ez 's/[^-]*-+[\n]*([^\n]*\n)[\n]*-+[^-]*/\1/g' input.txt

아니요 -E:

sed -z 's/[^-]*-\+[\n]*\([^\n]*\n\)[\n]*-\+[^-]*/\1/g' input.txt

참고: 이는 예제에서는 잘 작동하지만 -텍스트 어딘가에 발생하면 문제가 발생할 수 있습니다. 하지만 이에 대해 자세히 설명할 수 있을 것 같습니다.

관련 정보