Awk에서 정규 표현식을 변수에 저장할 때 정규 표현식이 필요할 때마다 해당 변수를 사용할 수 있나요?
Aho의 AWK 프로그래밍 언어는 다음과 같이 말합니다.
문자열 일치 패턴에 유의하세요.
/Asia/
는 약어이다
$O ~ /Asia/
텍스트 파일이 있습니다.
$ cat f1
line 1; li
ne
2
line 3
lin
e 4
다음 두 가지 방법이 작동하는 이유
$ awk -v pat='in' '{if (match($0, pat)) print $0; } ' f1
line 1; li
line 3
lin
$ awk -v pat='in' ' $0 ~ pat {print $0} ' f1
line 1; li
line 3
lin
그리고 따라오는 사람도 없지
$ awk -v pat='in' ' pat {print $0} ' f1
line 1; li
ne
2
line 3
lin
e 4
?
감사해요.
답변1
/foo/
'혼자'의 약어일 뿐입니다 $0 ~ /foo/
.
... ~ /.../
or ... 에서는 match(/.../, ...)
정규식에 대한 일종의 참조 연산자인 반면, 다른 컨텍스트에서는 숫자(0 또는 1)로 구문 분석하는 연산자에 가깝습니다.
이 이중 의미는 약간 혼란스러울 수 있습니다. 에는 이중 의미/모호함이 많이 있습니다 awk
.
/foo/
정규 표현식과 일치하는지 여부에 따라 $0
1 또는 0으로 확장되지만 정확히 일치하는 경우는 확장 foo
되지 "1" ~ /foo/
않으며 여기서는 더 이상 축약되지 않습니다. 또는 의 경우 다양한 구현이 다르게 동작하는 것을 볼 수 있습니다."1" ~ "1"
$0
foo
/foo/
($0 ~ /foo/)
"1" ~ (/foo/)
"1" ~ +/foo/
var
오직 var
.
var
as 조건은 변수가 숫자 또는 숫자의 문자열이고 0이 아닌 숫자로 확인되는 경우 또는 문자열이고 비어 있지 않은 문자열로 확인되는 경우 true를 의미합니다.
with로 선언된 변수는 -v var=value
숫자 및 문자열처럼 보이는 경우 숫자 문자열로 처리될 수 있는 변수 중 하나입니다.
awk -v var=in 'var {print "x"}'
x
in
숫자나 빈 문자열처럼 보이지 않으므로 각 레코드에 대해 인쇄합니다 .
awk -v var=0 'var {print "x"}'
인쇄되지 않습니다 x
. 및:
awk 'BEGIN{var = "0"}; var {print "x"}'
문자열 변수로 명시적으로 선언된 x
모든 레코드를 인쇄합니다. var
따라서 숫자처럼 보이지만 숫자로 간주되지는 않습니다.
이것은 이중 의미 중 또 다른 것입니다. 상황에 따라 변수는 숫자나 문자열로 처리될 수 있습니다. 또한 은 >
컨텍스트에 따라 비교 연산자 또는 리디렉션 연산자로 처리됩니다(이 역시 구현마다 동작이 달라지는 몇 가지 모호한 경우 중 하나입니다).
다음 작업도 수행할 수 있습니다.
awk '{print /foo/ + /bar/}'
이는 다음과 같습니다.
awk '{print ($0 ~ /foo/) + ($0 ~ /bar/)}'
하지만 대신 연결을 사용하면+
awk '{print /foo/ /bar/}'
/RE/
연산자와 /
나누기 연산자 사이에 모호함이 있기 때문에 이는 작동하지 않습니다 . 확실하지 않은 경우 괄호를 사용하세요.
awk '{print (/foo/) (/bar/)}'
그런데, 저장된 정규 표현식이나 백슬래시가 포함될 수 있는 모든 항목을 사용하지 말아야 합니다 -v
. ANSI 이스케이프 시퀀스가 확장되어 있기 때문입니다(GNU awk
4.2 이상,로 시작 @/
하고 끝나는 값 /
도 문제). 대신 환경 변수를 사용해야 합니다.
RE='\.txt$' awk '$0 ~ ENVIRON["RE"] {...}'
예를 들어.