abc.txt라는 구분된 파일이 있습니다. 열 이름이 쉼표(,)로 구분된 헤더 행이 있습니다. 모든 데이터 행과 헤더 행에 사용되는 행 구분 기호는 %=$%입니다(새 줄을 나타내는 줄 바꿈 없음). 데이터 행의 열 구분 기호는 |#@|입니다. Unix에서 데이터 행에 33개의 열이 없는 행을 찾는 방법은 무엇입니까?
답변1
Unbuntu 18에서 GNU Awk 4.1.4를 %=$%
레코드 구분 기호로 사용할 수 없습니다. 매크로가 들어있어요TXR 불분명한 음성일하다.
33개 필드 없이 레코드 인쇄:
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | \
txr -e '(awk (:set rs #/\%=$\%/ fs ",")
((= nr 1) (set fs #/\|#@\|/) (next))
((/= nf 33) (prn)))'
FOO|#@|BAR
X
TXR Lisp 정규 표현식은 이며 #/.../
연산자 %
(탐욕적이지 않은 버전 *
)이므로 이스케이프해야 합니다.
강제로 다시 계산하기 위해 필드 목록을 f
자체에 할당할 수 있습니다 .(set f f)
rec
ofs
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | \
txr -e '(awk (:set rs #/\%=$\%/ fs ",")
((= nr 1) (set fs #/\|#@\|/) (next))
((/= nf 33) (set f f) (prn)))'
FOO BAR
X
필드는 [f 0]
, [f 1]
이며 전체 레코드는 , 및 rec
와 다릅니다 . Awk에서와 마찬가지로 필드를 강제로 다시 계산하는 가장 짧은 방법입니다 .$1
$2
$0
(set f f)
rec
f
$1=$1
GNU Awk에서 동일한 방식으로 작동할 수 없는 이유 디버깅으로 돌아가서...
알고 있었다:
$ echo -n 'A,B,C,D%=$%FOO|#@|BAR%=$%X' | gawk \
'BEGIN { RS="%=\\$%"; FS = "," }
NR == 1 { FS = "\\|#@\\|" }
NF != 33 { $1=$1; print }'
A B C D
FOO BAR
X
next
규칙에서 누락되었으므로 NR == 1
헤더도 표시됩니다.
awk의 $
정규식 문자는 에서 이스케이프 처리해야 하는데 RS
그게 문제입니다. 물론 지금 나는 이것을 부정확하고 혼란스럽게 시도했습니다.
# incorrect escaping of $
$ gawk -v RS='%=\$%' ''
gawk: warning: escape sequence `\$' treated as plain `$'
하지만 여기서 우리가 하는 일은 정규식으로 해석되는 문자열을 할당하는 것입니다. Gawk는 \$
문자열 리터럴 구문에 이스케이프가 없다고 말합니다 . 이는 맞습니다. 그러나 우리에게 필요한 것은 달러 기호를 정규식 문자로 이스케이프하는 것입니다. 이를 Awk 문자열에 넣으려면 이를 이스케이프 처리 \\
한 다음 $
정규식 의미를 이스케이프 처리해야 합니다.