행 구분 기호가 %=$%(\n 문자 없음)이고 열 구분 기호가 |#@|인 경우 Unix에서 열 구분 기호 수가 다른 행을 찾는 방법은 무엇입니까?

행 구분 기호가 %=$%(\n 문자 없음)이고 열 구분 기호가 |#@|인 경우 Unix에서 열 구분 기호 수가 다른 행을 찾는 방법은 무엇입니까?

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)recofs

$ 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)recf$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 문자열에 넣으려면 이를 이스케이프 처리 \\한 다음 $정규식 의미를 이스케이프 처리해야 합니다.

관련 정보