awk에서 이스케이프 문자가 포함된 bash 변수를 사용하여 파일에서 줄 추출

awk에서 이스케이프 문자가 포함된 bash 변수를 사용하여 파일에서 줄 추출

저는 두 가지 패턴을 기반으로 파일에서 일부 줄을 추출하기 위해 bash 스크립트(bash 학습)를 작성하고 있습니다. 첫 번째 패턴은 콜론으로 끝나는 문장입니다. 두 번째 패턴은 *N(이 경우 58)회 반복됩니다.

예시 파일:

lines I don not want
lines I don not want
lines I don not want

A sentence here:
********************************************************
lines I want
lines I want
lines I want
**********************************************************

lines I don not want
lines I don not want
lines I don not want

원하는 출력:

A sentence here:
********************************************************
lines I want
lines I want
lines I want
**********************************************************

명시적으로 awk 호출을 58번 입력하면 A sentence here스크립트가 작동하도록 할 수 있지만 청결성과 가독성을 위해 다음과 같은 작업을 선호합니다.\*

pat1="A sentence here"
pat2=`printf -- '\*%.s' {1..58} ; echo`
pat2=${pat2//\\/\\\\}
awk -v pat1="${pat1}" -v pat2="${pat2}" '/{pat1}/ {p=1}; p; /{pat2}/ {p=0}' $1

첫 번째 위치 변수는 입력 파일입니다. 위의 코드는 아무것도 반환하지 않습니다. 처음에는 교체하지 않고 시도했지만 pat2경고가 표시되었습니다.

awk: warning: escape sequence `\*' treated as plain `*'

나는 이 명령을 수천 번 실행해야 하며 이상적으로는 깨끗하고 효율적인 솔루션을 원합니다. 나는 awk사용법에 전혀 의존하지 않습니다.

편집하다:

방금 awk에 패턴을 수동으로 입력하더라도 여전히 경고 메시지가 표시된다는 사실을 발견했습니다. 아마도 변수를 awk에 올바르게 전달하지 않았을 것입니다.

답변1

여기에는 몇 가지 옵션이 있습니다.

  • pat1, pat2는 정규식으로 처리됩니다.

    pat1="A sentence here"
    pat2='\*{58}'
    export pat1 pat2
    awk '$0 ~ ENVIRON["pat1"], $0 ~ ENVIRON["pat2"]'
    

    mawk4.0.0 이전 버전은 확장 정규식 연산자를 gawk지원하지 않는다는 점에 유의해야 합니다 . {}이전 버전의 경우 환경 변수를 전달하여 인식되도록 gawk할 수 있습니다 .POSIXLY_CORRECT

    여기서는 해당 방법이 사용되지만 태그 방법을 사용하여 동일한 작업을 수행 start-condition, end-condition [{action}]할 수 있습니다 .p

  • pat1, pat2는 고정 문자열로 처리됩니다.

    pat1="A sentence here"
    pat2=$(printf '*%.0s' {1..58})
    export pat1 pat2
    awk 'index($0, ENVIRON["pat1"]), index($0, ENVIRON["pat2"])'
    

    여기서 index()검색해보세요바늘(가변 내용)의 어느 곳에서나커다란 건초 더미(현재 레코드(행))이지만 간단한 전체 행 비교도 수행할 수 있습니다.

    awk '"" $0 == ENVIRON["pat1"], "" $0 == ENVIRON["pat2"]'
    

    ( 합계가 둘 다 숫자인 경우에도 ""문자열 비교가 강제됩니다 .)$0ENVIRON["patx"]

특정 C 이스케이프 시퀀스( , , ...)가 이를 처리 -v하므로 백슬래시 문자를 포함할 수 있는 데이터를 전달 하지 마십시오 . 따라서 백슬래시를 이스케이프해야 합니다(GNU 4.2 이상의 경우,awk\n\b\\awk로 시작 @/하고 끝나는 값 /도 문제). 이와 같이 전달된 변수도 마찬가지입니다 awk '...code...' awkvar="$shellvar". 사용 ENVIRON하거나 ARGV대체하십시오.

바라보다이 관련 질문에 대한 답변더 알아보기.

관련 정보