프로그래밍 방식으로 필드 구분 기호(FS)를 변경하고 gawk에서 현재 레코드를 다시 계산하시겠습니까?

프로그래밍 방식으로 필드 구분 기호(FS)를 변경하고 gawk에서 현재 레코드를 다시 계산하시겠습니까?

특정 레코드에 대한 필드 구분 기호( )만 변경 하고 FS새 필드 구분 기호를 사용하여 레코드( $0), 필드( $N) 및 필드 수( )를 다시 계산하려고 합니다. NF그러나 이것은 작동하지 않는 것 같습니다.

예:여기에는 공백으로 구분된 세 개의 필드로 해석되는 행이 있습니다. 필드 구분 기호를 로 변경하고 n레코드( $1 = $1)를 강제로 다시 작성하면 다음 인쇄에 표시된 대로 레코드가 변경되지 않은 상태로 유지됩니다 $1.

$ echo 'one two three' | awk '1 {FS="n" ; OFS=":" ; $1 = $1 ; print $1}'
> one

그러나 나는 출력이 다음과 같기를 원합니다.

> o

달리면서 기록 재구성을 강제하는 요령은 $1 = $1다음에서 따왔습니다.친구 매뉴얼. 그래서 나는 그것이 효과가 있기를 바랍니다. 문제가 무엇인지 잘 모르겠습니다.

FSOFS단순히 설정한 다음 일반 레코드를 기대 print하거나 print $0수정된 ​​레코드를 인쇄하여 레코드의 필드 구분 기호를 변경하려고 시도하는 것은 흔한 실수입니다.

그러나 레코드 자체를 변경하기 위해 아무 작업도 수행되지 않기 때문에 이는 작동하지 않습니다. 대신 일반적으로 $1 = $1[...] 와 같은 방법을 사용하여 레코드를 강제로 다시 작성해야 합니다.

(저는 GNU Awk 5.2.2를 사용하고 있습니다)

답변1

~에 대한

특정 레코드의 필드 구분 기호(FS)만 변경하고 싶습니다.

split()해당 레코드를 사용하면 코드가 더 깨끗하고 단순해질 수 있습니다.

$0을 다시 작성하고 $0을 다시 분할하는 두 가지 개념을 혼동하고 있습니다.

$0 재구축:필드에 값을 수정하거나 할당하면 $0이 필드에서 다시 작성되어 각 FS가 OFS로 대체됩니다.

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $1 = $1 ; print; for (i=1; i<=NF; i++) print i, $i}'
one:two:three
1:one
2:two
3:three

$0 재할당:$0에 값을 수정하거나 할당하면(필드 변경으로 인해 다시 빌드한 결과 제외) $0은 기존 FS 값을 사용하여 필드로 다시 분할됩니다.

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $0 = $0 ; print; for (i=1; i<=NF; i++) print i, $i}'
one two three
1:o
2:e two three

이제 다음 결과를 이해하고 위의 설명을 이해했는지 확인해 보세요.

다시 빌드한 후 다시 분할합니다.

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $1 = $1 ; $0 = $0; print; for (i=1; i<=NF; i++) print i, $i}'
one:two:three
1:o
2:e:two:three

다시 파티션을 나눈 후 다시 빌드하세요.

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $0 = $0; $1 = $1 ; print; for (i=1; i<=NF; i++) print i, $i}'
o:e two three
1:o
2:e two three

답변2

인용된 텍스트를 살펴보면 다음과 같습니다.

마지막으로 awksum 필드의 현재 값을 사용하여 전체 레코드를 강제로 다시 작성하는 것이 편리한 경우가 있습니다 OFS.

나중에 다음과 같습니다:

$0도메인과의 관계에는 또 다른 측면이 있습니다. 모든 할당으로 $0인해 레코드는 다음을 사용하여 필드로 다시 구문 분석됩니다.현재의의 가치 FS.

이전 문장에서는 언급하지 않고 FS두 번째 문장에서 강조하면 예상되는 방식은 다음과 같습니다. $0 = $0다른 쪽에서는 레코드가 변경됩니다.산출필드의 값이 무엇이든 구문 분석을 시도하지 않고 다음을 수행합니다.

% echo 'one two three' | awk '1 {FS="n" ; OFS=":" ; $0 = $0 ; print $1}'
o

% echo 'one two three' | awk '{FS="n" ; OFS=":" ; $1 = $1 ; print}'
one:two:three

저는 GNU awk를 사용하지 않습니다.

% awk --version
awk version 20200816

하지만 나는 GNU awk도 똑같이 할 수 있었으면 좋겠다.

관련 정보