시작 및 끝 패턴으로 정의된 여러 줄 범위 캡처

시작 및 끝 패턴으로 정의된 여러 줄 범위 캡처

파일의 중간 부분(시작 패턴과 끝 패턴 사이)을 인쇄하고 특정 줄에 색상을 지정하고 싶습니다.

다음은 그러한 파일 중 하나의 샘플 텍스트입니다.

## Beginning of file

Some text and code

## FAML [ASMB] KEYWORD
##  Some information.
##  Some other text.
##  Blu:
##  Some text in blue.
## END OF FAML [ASMB]

## Other text

More text and code

## FAML [ASMB] KEYWORD와 사이의 텍스트가 ## END OF FAML [ASMB]추출되어(시작 부분 없이 ##) 함수에 전달되어 luciferin여러 줄의 텍스트가 적절하게 인쇄됩니다.

블록 사이의 텍스트는 삭제됩니다. 후속 블록은 중간 영역을 추출하고 인쇄하는 함수를 호출하여 동일한 방식으로 작동합니다 luciferin(rec). 이 기능은 luciferin컬러로 출력합니다.

입력 문자열 luciferin

Some information.
Some other text.
Blu:
Some text in blue.

이것은 중간 영역을 캡처하는 awk 스크립트입니다.

BEGIN {
  beg_ere = "## [[:alnum:]]+ [[][[:alnum:]]+[]]"
  end_ere = "## END OF [[:alnum:]]+ [[][[:alnum:]]+[]]"
 }

match($0, beg_ere, paggr) { display = 1 }
$0 ~ end_ere { display = 0 ; next }
display { print }

luciferin문자열을 받아서 컬러로 출력하는 함수 입니다 . 여기서, cpt색상 이스케이프 시퀀스에서 및 는 astr[i]여러 줄 입력 문자열의 특정 줄입니다.i

function luciferin(mstr) {
  cpt = tseq["Grn:"]
  nlines = split(mstr, astr, "\n")
  for (i = 1; i <= nlines; i++) {
    for ( knam in tseq ) {
      if ( knam == astr[i] ) { cpt = tseq[knam] ; break }
     }
    if (knam == str) { print "" } else { print cpt astr[i] rst }
   }

 }

답변1

최소한의 완전한 코드 예제도 없고 테스트할 충분한 샘플 입력/출력도 없기 때문에 이는 확실히 테스트되지 않은 추측일 뿐이지만 변경해야 할 것 같습니다.

display { print }

도착하다

display { rec = rec $0 ORS }

그리고

$0 ~ end_ere { display = 0 ; next }

도착하다

$0 ~ end_ere { luciferin(rec); rec = ""; display = 0 ; next }

또는 유사하며 luciferin인쇄하기 전에 인수에서 추가 후행 개행 문자를 제거하도록 조정되었습니다.


이 질문과 OP의 질문을 개선하는 방법에 대해 다음과 같은 질문에서 완전하고 최소한의 코드 예제가 어떻게 보이는지 보여줍니다.

$ cat tst.awk
$2 == "FAML" { display = 1 ; next }
$2 == "END" { display = 0 ; next }
display { print }

function luciferin(mstr) {
    nlines = split(mstr, astr, "\n")
    for (i = 1; i <= nlines; i++) {
        print "Luci:", astr[i]
    }
}

요구 사항을 보여주고 테스트하기 위한 몇 가지 입력 예는 다음과 같습니다.

$ cat input
## Beginning of file

Some text and code

## FAML [ASMB] KEYWORD
##  Some information.
##  Some other text.
## END OF FAML [ASMB]

## Other text

## FAML [ASMB] KEYWORD
##  Some other information.
##  Even more text.
## END OF FAML [ASMB]

More text and code

그리고 입력이 주어지면 예상되는 출력은 다음과 같습니다.

Luci: ##  Some information.
Luci: ##  Some other text.
Luci: ##  Some other information.
Luci: ##  Even more text.

실제 코드가 색상 지정이나 다른 작업을 수행한다는 사실은 도움이 필요한 문제와 전혀 관련이 없으며 텍스트 블록을 저장하고 luciferin()이를 인쇄하기 위해 어떤 방식으로든 수정하기 위해 호출하는 방법일 뿐입니다.

명확하고 간단한 예를 통해 다음과 같은 솔루션을 신속하게 보여줄 수 있습니다.

$ cat tst.awk
$2 == "FAML" { display = 1 ; next }
$2 == "END" { luciferin(rec); rec = ""; display = 0 ; next }
display { rec = rec $0 ORS }

function luciferin(mstr) {
    nlines = split(mstr, astr, "\n")
    for (i = 1; i < nlines; i++) {
        print "Luci:", astr[i]
    }
}

$ awk -f tst.awk input
Luci: ##  Some information.
Luci: ##  Some other text.
Luci: ##  Some other information.
Luci: ##  Even more text.

그런 다음 개념을 실제 코드에 적용할 수 있습니다.

답변2

이 문제를 해결하는 것은 awk확실히 가능합니다 . 하지만 당신 스스로는 이 문제를 너무 어렵게 만들고 있는 것 같습니다. 주석에 언급된 기능에서 복사하여 Perl해당 범위에 대해 직접 언어 지원을 제공합니다 .sed

봄을 파란색으로 칠해 봅시다.

$ cat months.txt | perl -ane 'print "blue" if /Mar/../May/; print "\t$_"'
        January
        February
blue    March
blue    April
blue    May
        June

이러한 정규식에 FAML/ASMB 키워드를 사용하여 사용 사례에 맞게 조정하세요.


이보다 더 고급 처리를 원하더라도 여전히 파이프라인의 좋은 초기 단계입니다.

이제 후속 단계에서는 행 범위에 대해 걱정할 필요가 없습니다. 첫 번째 필드를 사용하여 범위 내에 있는지 확인한 다음 그에 따라 행의 나머지 부분을 처리할 수 있습니다.

관련 정보