John Goldenrod:(916) 348-4278:250:100:175
Chet Main:(510) 548-5258:50:95:135
Tom Savage:(408) 926-3456:250:168:200
Elizabeth Stachelin:(916) 440-1763:175:75:300
출력에는 4자 이름(john, chet)만 포함된 줄이 포함되어야 합니다.
awk '$1 ~ /[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]" "/ {print}' file
이것은 나에게 적합하지 않은 것 같습니다. awk 함수를 사용하지 않고도 이 작업을 수행할 수 있나요?
답변1
awk의 필드는 기본적으로 " "로 구분됩니다. 이는
$1
공백이 없음을 의미하므로 올바른 정규식은 $1
다음과 같습니다.
awk '$1 ~ /^[a-zA-Z0-9]{4}$/ {print}' file
원래 방법을 유지하려면 $0
다음과 같이 사용할 수도 있습니다.
awk '$0 ~ /^[a-zA-Z0-9]{4}\s/ {print}' file
\w
단순화하기 위해 단어 문자를 명시적으로 정의하는 대신 다음과 같이 사용할 수도 있습니다 .
awk '$0 ~ /^\w{4}\s/ {print}' file
공백만 일치시키고 다른 것은 일치시키지 않으려면 " "(따옴표 제외) 로 TAB
바꾸십시오 .\s
원래 접근 방식의 또 다른 문제는 앵커 포인트가 없다는 것입니다. 지정하지 않았으므로 패턴이 어디에도 나타날 수 없습니다. 즉, 패턴이 와 ^
일치 합니다 .$
Elizabeth Stachelin
beth
답변2
AWK에서는 정규식을 다음과 같이 사용할 수 있습니다.무늬AWK 스크립트에서 자주 볼 수 있는 것과 같습니다 BEGIN
. END
단순화된 코드는 다음과 같습니다
awk '/^[[:alnum:]]{4}\>/'
이것이 귀하의 요구 사항을 충족하는 데 필요한 전부입니다. 당신은 필요하지 않습니다행동, {print}
패턴 일치 시 기본 작업으로 전체 레코드, 즉 전체 라인을 인쇄합니다.
[:alnum:]
[a-zA-Z0-9]
로케일에 따라 기본적으로 동의어입니다 . 사용할 수도 있습니다 \w
. 단, _
underscore 의 약어인 underscore 도 포함되어 있습니다 [[:alnum:]_]
.
awk '/^\w{4}\>/'
\>
단어의 끝을 일치시킵니다. 이를 사용하면 John:(###)...
전체 이름이 포함되지 않은 레코드가 있는 경우 문자열을 올바르게 일치시킬 수 있습니다.
AWK에 대해 문의하셨지만 sed
이 경우 AWK보다 거의 두 배 빠른 속도로 실행되는 AWK를 사용하는 것이 좋습니다.
sed -n '/^[[:alnum:]]\{4\}\b/p'
\b
예 \>
또는 \<
AWK입니다. 500,000개 라인을 테스트했고, 100,000개 라인을 매칭했는데, AWK는 약 1.7초가 걸렸고, sed는 0.9초밖에 걸리지 않았습니다. 그러나 테스트 사례는 극단적이며 이는 단지 까다로운 제안일 뿐입니다.
나는 또한 읽기 man 7 regex
를 man awk
권합니다 info awk
.
답변3
첫 번째 필드는 이고 $1
길이는 이므로 length($1)
다음과 같습니다.
awk 'length($1) == 4 {print}'
아니면 좀 더 간략하게
awk 'length($1) == 4'
당신이 쓴 내용이 작동하지 않는 데에는 두 가지 이유가 있습니다. 먼저 " "
정규식에 추가 항목이 있으므로 필드에 큰따옴표, 공백, 큰따옴표가 포함되어야 합니다. 이 문제를 해결하면 /[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/
4개 이상의 ASCII 문자 또는 숫자가 포함된 필드와 일치하지만 그 이상을 포함할 수 있으므로 와 일치 Elizabeth
하지만 는 일치 John
하지 않습니다 Tom
. 시작과 끝 부분에 고정된 정규식을 작성할 수 있지만 /^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$/
원하는 것이길이필드의 경우 이렇게 작성하면 됩니다.