awk에서 물결표 ~ 연산자를 사용할 때 이스케이프 시퀀스는 어디에 필요합니까?

awk에서 물결표 ~ 연산자를 사용할 때 이스케이프 시퀀스는 어디에 필요합니까?

pattern다음 값을 가진 변수가 있습니다 .

\"something//\\anotherthing'

다음을 포함하는 파일:

\"something//\\anotherthing'
\"something//\\anotherthing
\"something/\anotherthing'
\"something\anotherthing'
\\"something\/\/\\\\anotherthing'

파일에서 읽은 줄을 ==환경의 패턴 및 연산자와 비교하면 예상되는 출력을 얻습니다.

patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 == ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \"something//\\anotherthing'    YES
\"something//\\anotherthing     \"something//\\anotherthing'    NO
\"something/\anotherthing'      \"something//\\anotherthing'    NO
\"something\anotherthing'       \"something//\\anotherthing'    NO
\\"something\/\/\\\\anotherthing'       \"something//\\anotherthing'    NO

하지만 연산자로 동일한 작업을 수행하면 ~테스트가 일치하지 않습니다. ( YES위와 같이 첫 번째 줄에 기대합니다 ):

patt="$pattern" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \"something//\\anotherthing'    NO
\"something//\\anotherthing     \"something//\\anotherthing'    NO
\"something/\anotherthing'      \"something//\\anotherthing'    NO
\"something\anotherthing'       \"something//\\anotherthing'    NO
\\"something\/\/\\\\anotherthing'       \"something//\\anotherthing'    NO

비교하여 문제를 해결하려면 ~이스케이프를 두 번 이스케이프해야 합니다.

patt="${pattern//\\/\\\\}" awk '{print $0, ENVIRON["patt"], ($0 ~ ENVIRON["patt"]?"YES":"NO") }'  OFS="\t" file
\"something//\\anotherthing'    \\"something//\\\\anotherthing' YES
\"something//\\anotherthing     \\"something//\\\\anotherthing' NO
\"something/\anotherthing'      \\"something//\\\\anotherthing' NO
\"something\anotherthing'       \\"something//\\\\anotherthing' NO
\\"something\/\/\\\\anotherthing'       \\"something//\\\\anotherthing' NO

ENVIRON["patt"]두 번째 열의 인쇄된 결과에서 이중 이스케이프를 확인하세요.

질문:

이스케이프 시퀀스는 어디에 있습니까?물결표 ~비교 연산자를 사용할 때 이런 일이 발생합니까? 켜짐 $0(또는 $1,, $2...) 또는 켜짐 ENVIRON["variable"]?

답변1

~연산자는 패턴 일치를 수행하여 오른쪽 피연산자를 (확장) 정규식으로 처리하고 왼쪽 피연산자를 문자열로 처리합니다.POSIX설명하다:

두 개의 정규식 일치 연산자 '~'"!~". 이러한 연산자는 오른쪽 피연산자를 정규식으로 해석하고 왼쪽 피연산자를 문자열로 해석해야 합니다.

so는 ENVIRON["patt"]정규식으로 처리되며 다음이 필요합니다.ERE의 모든 특수 문자일반적인 ERE 의미를 갖지 않으려면 이스케이프할 수 있습니다.


이것은 $0또는 를 사용하는 것이 ENVIRON["name"]아니라 물결표의 왼쪽과 오른쪽에 관한 것입니다. 이는 입력 행(in $0)을 일치시킬 정규식으로 사용합니다.

str=foobar awk 'ENVIRON["str"] ~ $0 { 
     printf "pattern /%s/ matches string \"%s\"\n", $0, ENVIRON["str"] }'

답변2

\정규식의 A는 다음 문자를 이스케이프하거나 이스케이프 시퀀스를 도입합니다. \리터럴을 정규식과 일치시키 려면 ( ~연산자가 에서 수행하는 작업 awk) 다음을 사용해야 합니다 \\(질문의 마지막 예에서 이 작업을 수행함). 문자열 비교에서는 이것이 필요하지 않습니다.

관련 정보