내 쉘 함수 중 하나에 다음이 포함됩니다.
function _process () {
awk -v l="$line" '
BEGIN {p=0}
/'"$1"'/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
}
그래서으로 전화했을 때 _process $arg
, $arg
로 전달됩니다 $1
및 검색 패턴으로 사용. 쉘 $1
이 awk 패턴 대신 확장되기 때문에 이런 식으로 작동합니다 ! 또한 l
, AWK 프로그램 내에서 사용할 수있는 선언되고 -v l="$line"
. 다 괜찮아
같은 방식으로 패턴을 변수로 검색 할 수 있습니까?
다음은 작동하지 않습니다.
awk -v l="$line" -v search="$pattern" '
BEGIN {p=0}
/search/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
awk는 /search/
변수로 해석되지 않고 문자 그대로 해석합니다.
답변
awk의 ~
연산자를 사용 하면 오른쪽에 리터럴 정규식을 제공 할 필요가 없습니다.
function _process () {
awk -v l="$line" -v pattern="$1" '
$0 ~ pattern {p=1}
END {if(p) print l >> "outfile.txt"}
'
}
이것이 더 효율적이지만 (전체 파일을 읽을 필요는 없습니다)
function _process () {
grep -q "$1" && echo "$line"
}
패턴에 따라 원하는 경우가 있습니다 grep -Eq "$1"
답변
awk -v pattern="$1" '$0 ~ pattern'
awk
에서 ANSI C 이스케이프 시퀀스 (예 \n
: 줄 바꿈, \f
양식 피드, \\
백 슬래시 등) 를 확장 하는 문제 가 $1
있습니다. 따라서 $1
정규 표현식에서 공통적 인 백 슬래시 문자가 포함되어 있으면 문제가됩니다 (GNU awk
4.2 이상에서는으로 시작 @/
하고 끝나는 값 /
도 문제가됩니다 ). 이 문제로 어려움을 겪지 않는 또 다른 접근법은 다음과 같이 작성하는 것입니다.
PATTERN=$1 awk '$0 ~ ENVIRON["PATTERN"]'
그것이 얼마나 나쁜지는 awk
구현에 달려 있습니다 .
$ nawk -v 'a=\.' 'BEGIN {print a}'
.
$ mawk -v 'a=\.' 'BEGIN {print a}'
\.
$ gawk -v 'a=\.' 'BEGIN {print a}'
gawk: warning: escape sequence `\.' treated as plain `.'
.
$ gawk5.0.1 -v 'a=@/foo/' BEGIN {print a}'
foo
awk
유효한 이스케이프 시퀀스에 대해 모든 것이 동일하게 작동합니다.
$ a='\\-\b' awk 'BEGIN {print ENVIRON["a"]}' | od -tc
0000000 \ \ - \ b \n
0000006
( $a
통과 그대로 내용 )
$ awk -v a='\\-\b' 'BEGIN {print a}' | od -tc
0000000 \ - \b \n
0000004
( \\
변경 \
및 \b
백 스페이스 문자로 변경).
답변
다음과 같은 것을 시도하십시오 :
awk -v l="$line" -v search="$pattern" 'BEGIN {p=0}; { if ( match( $0, search )) {p=1}}; END{ if(p) print l >> "outfile.txt" }'
답변
아니요, 그러나 awk에 전달하는 큰 따옴표로 묶은 문자열에 패턴을 보간 할 수 있습니다.
awk -v l="$line" "BEGIN {p=0}; /$pattern/ {p=1}; END{ if(p) print l >> \"outfile.txt\" }"
큰 따옴표로 묶인 awk 리터럴을 이스케이프해야하지만 여전히 가장 간단한 방법입니다.
답변
이 예제에서 awk가 실행되기 전에 nets 변수를 해결하는 eval 함수를 사용할 수 있습니다.
nets="searchtext"
eval "awk '/"${nets}"/'" file.txt