[unix] 쉘 변수를 awk에 / pattern /으로 전달하십시오.

내 쉘 함수 중 하나에 다음이 포함됩니다.

function _process () {
  awk -v l="$line" '
  BEGIN {p=0}
  /'"$1"'/ {p=1}
  END{ if(p) print l >> "outfile.txt" }
  '
}

그래서으로 전화했을 때 _process $arg, $arg로 전달됩니다 $1및 검색 패턴으로 사용. 쉘 $1이 awk 패턴 대신 확장되기 때문에 이런 식으로 작동합니다 ! 또한 l, AWK 프로그램 내에서 사용할 수있는 선언되고 -v l="$line". 다 괜찮아

같은 방식으로 패턴을 변수로 검색 할 수 있습니까?

다음은 작동하지 않습니다.

awk -v l="$line" -v search="$pattern" '
  BEGIN {p=0}
  /search/ {p=1}
  END{ if(p) print l >> "outfile.txt" }
  '

awk는 /search/변수로 해석되지 않고 문자 그대로 해석합니다.



답변

awk의 ~연산자를 사용 하면 오른쪽에 리터럴 정규식을 제공 할 필요가 없습니다.

function _process () {
    awk -v l="$line" -v pattern="$1" '
        $0 ~ pattern {p=1}
        END {if(p) print l >> "outfile.txt"}
    '
}

이것이 더 효율적이지만 (전체 파일을 읽을 필요는 없습니다)

function _process () {
    grep -q "$1" && echo "$line"
}

패턴에 따라 원하는 경우가 있습니다 grep -Eq "$1"


답변

awk  -v pattern="$1" '$0 ~ pattern'

awk에서 ANSI C 이스케이프 시퀀스 (예 \n: 줄 바꿈, \f양식 피드, \\백 슬래시 등) 를 확장 하는 문제 가 $1있습니다. 따라서 $1정규 표현식에서 공통적 인 백 슬래시 문자가 포함되어 있으면 문제가됩니다 (GNU awk4.2 이상에서는으로 시작 @/하고 끝나는 값 /도 문제가됩니다 ). 이 문제로 어려움을 겪지 않는 또 다른 접근법은 다음과 같이 작성하는 것입니다.

PATTERN=$1 awk '$0 ~ ENVIRON["PATTERN"]'

그것이 얼마나 나쁜지는 awk구현에 달려 있습니다 .

$ nawk -v 'a=\.' 'BEGIN {print a}'
.
$ mawk -v 'a=\.' 'BEGIN {print a}'
\.
$ gawk -v 'a=\.' 'BEGIN {print a}'
gawk: warning: escape sequence `\.' treated as plain `.'
.
$ gawk5.0.1 -v 'a=@/foo/' BEGIN {print a}'
foo

awk유효한 이스케이프 시퀀스에 대해 모든 것이 동일하게 작동합니다.

$ a='\\-\b' awk 'BEGIN {print ENVIRON["a"]}' | od -tc
0000000   \   \   -   \   b  \n
0000006

( $a통과 그대로 내용 )

$ awk -v a='\\-\b' 'BEGIN {print a}' | od -tc
0000000   \   -  \b  \n
0000004

( \\변경 \\b백 스페이스 문자로 변경).


답변

다음과 같은 것을 시도하십시오 :

awk -v l="$line" -v search="$pattern" 'BEGIN {p=0}; { if ( match( $0, search )) {p=1}}; END{ if(p) print l >> "outfile.txt" }'


답변

아니요, 그러나 awk에 전달하는 큰 따옴표로 묶은 문자열에 패턴을 보간 할 수 있습니다.

awk -v l="$line" "BEGIN {p=0}; /$pattern/ {p=1}; END{ if(p) print l >> \"outfile.txt\" }"

큰 따옴표로 묶인 awk 리터럴을 이스케이프해야하지만 여전히 가장 간단한 방법입니다.


답변

이 예제에서 awk가 실행되기 전에 nets 변수를 해결하는 eval 함수를 사용할 수 있습니다.

nets="searchtext"
eval "awk '/"${nets}"/'" file.txt


답변