한 줄을 인쇄해야 하지만 숫자를 검색하려면 awk를 사용하고 더 많은 숫자와 함께 이중 콜론을 추가해야 하는 시나리오가 있습니다.
아래 예를 참조하세요.
test1 test2 37:375003 test3 test4
test1 test2 38:375004 test3 test4
test1 test2 39:375005 test3 test4
test1 test2 40:375006 test3 test4
test1 test2 41:375007 test3 test4
내가 달성하고 싶은 것은 다음과 같은 명령을 사용하는 것입니다.
cat test_out.txt | awk "{if ($3 == 37~/\:*/ ) print $0;}"
위 내용은 다음 줄을 제공합니다.
test1 test2 37:375003 test3 test4
다음 구문 오류가 발생합니다.
Syntax Error The source line is 1.
The error context is
{if ( >>> == <<<
awk: 0602-502 The statement cannot be correctly parsed. The source line is 1.
답변1
~
구문은 다음과 같은 이항 연산자를 사용해야 합니다 .
string ~ regexp
문자열을 정규식과 일치시키려면 다음을 수행하십시오.
<test_out.txt awk '$3 ~ /^37:[[:digit:]]+$/'
세 번째 필드가 확장 정규식( {print}
기본 작업의 약어)과 일치하는 레코드를 인쇄합니다.{print $0}
^37:[[:digit:]]+$
ERE 구문에서:
^
주제의 시작 부분과 일치[...]
: 세트의 모든 문자 또는 조합 요소와 일치합니다.[:digit:]
위의 집합은 로케일에서 10진수로 분류된 모든 문자를 나타냅니다(대부분의 시스템에서는 0123456789로 제한됨). 다른 십진수와 일치하지 않으려면0123456789
지원되지 않는 POSIX 문자 클래스로 변경하세요. 또한 작동하지만 일부 구현에서는 다른 문자와 일치할 수도 있습니다.mawk
0-9
mawk
awk
+
위의 항목 중 하나 이상을 대상으로 합니다. 여기 하나 이상의 숫자가 있습니다$
주제의 끝과 일치합니다.
다음 부분이 숫자로 구성되어 있는지 신경 쓰지 않는다면 37:
정규 표현식은 ^37:
( 37:
주제 시작 부분)입니다.
또 다른 방법은 다음과 같습니다.
<test_out.txt awk '$3 + 0 == 37'
+ 0
숫자 연산은 초기 숫자 뒤의 모든 항목을 무시하고 숫자로 awk
변환을 시도합니다. $3
그러면 이는 일치 37:anything
하지만 일부 구현 과 일치 할 수 있는 37.0;whatever
1, 3.7e+1
1 도 일치합니다 . 표준을 사용하더라도 일부 구현에서는 작동하지 않습니다 .0x25#xxx
awk
+37+38
+$3 == 37
awk
37
쉘 변수(여기)에서 오는 값의 경우 쉘에서 정규 표현식을 구성하고 이를 ment 변수를 awk
통해 전달할 수 있습니다.ENVIRON
var=37
ERE='^'$var':[[:digit:]]+$' <test_out.txt awk '$3 ~ ENVIRON["ERE"]'
또는 awk
v
쉘 변수에서 변수²를 생성하십시오.
var=37
<test_out.txt awk -v n="$var" '$3 ~ "^" n ":[[:digit:]]+"'
다음과 같이 셸 변수를 awk
코드로 확장하지 마세요.
<test_out.txt awk '$3 ~ /^'"$var"':[[:digit:]]+$/'
이로 인해 종종 명령 주입 취약점(최악의 취약점 유형)이 발생하기 때문입니다.
귀하의 시도에 대한 몇 가지 의견:
- 이미 똑같아@RudyC가 지적함, awk 코드 주위에 큰따옴표를 사용했습니다. 쉘은 거기에서 매개변수 확장을 수행하므로
$3
쉘 스크립트의 세 번째 매개변수 값과$0
스크립트 이름이 확장됩니다. $3 == 37 ~ /\:*/
.==
다음보다 높은 우선순위~
. 그래서 그것은($3 == 37) ~ /\:*/
. 이는\:*
정규식을 비교 결과와 일치시킵니다($3
37인지 여부에 따라 1 또는 0).\:*
정규식이 지정되지 않았기 때문에\:
지정되지 않았습니다 . text 와 일치하려면 단독:
입니다:
.:*
0 또는 그 이상이 될 것이므로:
문자열에 최소 0:
이 포함되어 있으므로 무엇이든 일치합니다.*
정규식에서 0개 이상의 이전 항목과 일치합니다.*
이를 0개 이상의 문자와 일치하는 쉘 와일드카드와 혼동 할 수 있습니다 . 정규식에서 0개 이상의 문자는 단일 문자와 일치하는 연산자.*
입니다 ..
awk
명령문의 형식은condition {action}
다음과 같습니다.상황또는행동생략 가능합니다. 귀하의 경우에는 생략했습니다.상황그리고if
사용행동,{print $0}
기본값인 것을 사용합니다.행동. 이것이 작동하는 동안에는 매우 사용자awk
친화적 이지 않을 수 있습니다awk
.- 거의 의미가 없는 파일을
cat
연결한 적이 있습니다 .cat
쉘은 리디렉션을 사용하여 파일 자체를awk
표준 입력으로 열 수 있으므로 프로세스를 절약하고 파이프를 통해 항목을 푸시할 필요가 없습니다. 파일 이름을 매개변수로 전달하면awk
파일이 자동으로 열립니다.
1 적어도 일부 구현(예: POSIX 모드의 GNU)에서는 소수 기수 문자가 로케일에 있고 로케일에는 .
없다고 가정합니다.,
awk
awk
² -v
백슬래시는 ENVIRON
일반적으로 사용하기에 더 안전하도록 맹글링되어 있습니다.
답변2
"
첫 번째 실수는 스크립트에서 큰따옴표를 사용하는 것입니다 awk
. 이로 인해 쉘이 $3
쉘에 있는 모든 항목으로 확장됩니다(이 경우 빈 문자열일 수 있음). '
대신 작은따옴표나 파일을 사용하세요 .
그런 다음 다른 답변에 표시된 대로 작업에 맞는 올바른 정규식을 사용하세요.