awk 정규식 일치에 문제가 있습니다. 특정 열을 정규식 패턴과 일치시키려고 합니다 (\"\.\"|0|1)
. 이 열에는 "."
또는 값만 포함될 수 있습니다 0
. 1
하지만 내 정규식 패턴은 awk에서 일치하지 않는 반면 열의 데이터는 "."
. 어떤 아이디어가 있나요? ?
암호
awk -F "$delimitter" -v n="$column" -v m="$pattern" 'NR!=1 && $n !~ "^" m "$" {
printf "%s:%s:%s\n", FILENAME, FNR, $n > "/dev/stderr"
count++
}
END {print count+0}' input.txt 2>> errors.log
답변1
"."
패턴이 (따옴표 포함) 또는 정확히 일치하도록 하려면 패턴이 또는 등 0
이어야 합니다 .1
^("\."|[01])$
^("[.]"|[01])$
^("\."|0|1)$
그러나 다음 을 사용하여 -v
해당 패턴을 전달할 때awk
awk
\
-F x
-v FS=x
이 문제는 존재하지 않으므로 ENVIRON
셸에서 임의의 문자열을 전달하는 것이 더 좋습니다 .awk
그래서:
pattern='"\."|0|1'
PATTERN=$pattern DELIMITER=$delimiter awk -v n="$n" '
BEGIN {FS = ENVIRON["DELIMITER"]; m = ENVIRON["PATTERN"]}
$n ~ "^(" m ")$" {...}'
( 숫자일 것으로 예상되므로 여전히 -v
for를 사용하므로 백슬래시가 없습니다.)n
위의 (
를 참고하세요 )
. 처음이든 끝이든 ^x|y$
.x
y
답변2
텍스트를 일치시킬 때 "패턴"이라는 단어는 매우 모호하므로 사용하지 마세요. 참조하는 "문자열" 또는 "정규 표현식"을 사용하십시오. 바라보다패턴과 일치하는 텍스트를 찾는 방법더 많은 정보를 알고 싶습니다.
이 버그를 해결하고 해시 조회의 문자열 비교가 더 깨끗하고 덜 불안정하며 더 효율적인 정규식 비교를 사용하는 것 같습니다.
valid='"."|0|1'
awk -F "$delimitter" -v n="$column" -v m="$valid" '
BEGIN {
split(m,tmp,"|")
for (i in tmp) {
valid[tmp[i]]
}
}
NR>1 && !($n in valid) {
printf "%s:%s:%s\n", FILENAME, FNR, $n > "/dev/stderr"
count++
}
END {print count+0}
' input.txt
쉘 변수에 이스케이프 시퀀스가 포함될 수 있는 경우(예제의 변수에는 포함되지 않음)https://stackoverflow.com/questions/19075671/how-do-i-use-shell-variables-in-an-awk-script또는 -v
와 같이 값을 awk에 전달하는 것 이외의 다른 방법입니다 .ENVIRON[]
ARGV[]
답변3
당신의 패턴으로 사용해 보세요 [.01]
.
.
, 0
및 에만 일치하는 대괄호 표현식입니다 1
.
.
참고: 대괄호 표현식 외부에서는 다음 으로 이스케이프해야 합니다 \.
(그렇지 않으면 모든 문자와 일치함). 그러나 대괄호 표현식 내부에서는 리터럴로 처리됩니다..