awk 출력의 제어 문자

awk 출력의 제어 문자

나는 다음 bash/ awk스크립트를 가지고 있으며 의미를 모르는 제어 기호를 추가하는 것을 제외하고는 내가 원하는 것을 수행합니다.

#!/usr/bin/env bash

# Merge two cross section files from Resummino

file1=filein1
file2=filein2
fileout=fileout

awk '{
        xs_nlo[$1," ",$2] += $4
        xs_lo[$1," ",$2] += $3
    }
    END {
        for (xs in xs_nlo){
            print(xs, xs_lo[xs], xs_nlo[xs])
        }
    }
' "${file1}" "${file2}"

가능한 내용 filein1:

100.000 500.000 7.878892e+00 1.027803e+01
100.000 1000.000 9.667085e+00 1.274467e+01
100.000 2000.000 1.029358e+01 1.361803e+01
100.000 5000.000 1.049836e+01 1.390297e+01
100.000 10000.000 1.052944e+01 1.394593e+01

와 유사 filein2하지만 각 행의 마지막 두 값이 다릅니다. 스크립트 awk는 첫 번째 값과 두 번째 값이 동일하다고 가정하고 각 행에 세 번째 값을 추가해야 합니다. 네 번째 값도 마찬가지입니다.

출력 파일은 입력 파일과 동일한 구조를 가져야 합니다. 콘솔에서 출력 파일은 동일해 보이지만, 콘솔에서 열면 vim쉽게 검색할 수 없는 제어 문자가 보입니다.

100.000^\ ^\300.000 3.42 4.57283

무슨 뜻이에요 ^\ ^\? 어떻게 제거할 수 있나요?

답변1

문제의 원인은 구분 기호입니다 $1," ",$2.

문서에서:

awk는 인덱스를 문자열로 연결하여 다차원 배열을 지원합니다. awk는 인덱스를 문자열로 변환하고(변환 참조) 인덱스 사이를 구분 기호로 연결합니다. 그러면 개별 인덱스 값을 설명하는 단일 문자열이 생성됩니다. 결합된 문자열은 일반 1차원 배열에 대한 단일 인덱스로 사용됩니다. 사용된 구분 기호는 내장 변수의 값입니다.하위 집합


하위 집합
아래 첨자 구분 기호입니다. 기본값은 "\034"이며 다차원 배열의 인덱스 부분을 분리하는 데 사용됩니다. 따라서 'foo["A", "B"]' 표현식은 실제로 foo["A\034B"]에 액세스합니다.


표준 awk는 아래 첨자 값을 쉼표로 구분하여 다차원 배열을 에뮬레이트합니다. 이러한 값은 SUBSEP 값으로 구분된 단일 문자열로 연결됩니다.
따라서 이러한 첨자가 이러한 방식으로 생성된다는 사실은 유지되지 않습니다.하위 집합의도하지 않은 결과가 발생할 수 있습니다.

답변2

두 번째 부분의 경우:

^\ ^\는 무엇을 의미하며 어떻게 제거할 수 있나요?

다른 답변에서는 쉼표( ,)가 [$1," ",$2]SUBSEP가 되는 위치를 설명했습니다. Thta는 문자 \034(8진수) 또는 0x1C(16진수)입니다.

이 문자는 컨트롤 인코딩에도 쓸 수 있습니다 ^\. 그렇기 때문에 둘 다 출력에
포함됩니다 .^\

해결책은 배열 인덱스가 생성되는 방식에 대한 제어권을 (awk 프로그램에서) 되찾는 것입니다. 가장 간단한 해결책은 두 필드( $1$2)를 함께 연결하는 것입니다. 그러나 이렇게 하면 두 배열 키가 동일해집니다(언어에 관계 없음).

$1=abc  $2=def     $1$2 is abcdef
$1=a    $2=bcdef   $1$2 is abcdef

해결 방법은 $1 또는 $2 값에 표시되지 않는 문자를 사용하는 것입니다. 공백이 후보로 보이지만 FS(Field Separator)는 인쇄 시 필드도 구분하는 보다 일반적인 솔루션입니다. 따라서 이 스크립트는 모든 FS에서 작동합니다.

#!/bin/bash

# Merge two cross section files from Resummino

file1=filein1
file2=filein2
fileout=fileout


awk 'BEGIN{OFS=FS} {
          point = $1 FS $2
          xs_nlo[ point ] += $4
          xs_lo [ point ] += $3
     }
     END {
         for (xs in xs_nlo){
             print(xs, xs_lo[xs], xs_nlo[xs])
         }
     }
    ' "${file1}" "${file2}"

답변3

xs_nlo[$1," ",$2]고치 려면 교체 하세요 xs_nlo[$1" "$2].

관련 정보