awk 내의 일치를 기반으로 awk 변수를 변경합니다.

awk 내의 일치를 기반으로 awk 변수를 변경합니다.

gnuplot으로 보내기 전에 전처리 중인 데이터 파일이 있습니다. 헤더 행과 여러 데이터 행으로 구성되며 많은 데이터 유형 열이 있습니다. 처음 세 개의 열은 항상 동일한 유형과 순서를 갖습니다. 총 열 수는 파일 내에서는 일정하지만 파일 간에는 일정하지 않습니다. seqno는 1부터 시작하는 것이 보장되지 않지만 항상 단조롭게 증가합니다.

데이터 파일에서 원하는 위치에 헤더 행을 삽입하는 스크립트가 있는데 현재 일치하는 항목에 따라 해당 헤더를 변경할 수 있기를 원합니다. 특히 $i 변수를 네 번째 변수에 추가하고 싶습니다. 5번째, ..endth 열이 헤더입니다. 그 외에는 각 위치의 제목이 동일합니다.

이는 스크립트로 실행되므로 헤더에 포함된 열 수를 확인하기 위해 헤더를 전처리해야 하는 경우 쉽게 수행할 수 있습니다.

필요한 헤더 교체가 없는 현재 스크립트는 다음과 같습니다(마지막에 다른 헤더 예제가 있음).

header=$(head -n1 $input)
awk -v i=3 -v hdr="$header" 'NR>1 && $i!=p {print "\n\n"hdr}{p=$i} 1' ${input} > ${output}

내 입력 예는 다음과 같습니다

#filename       seqno   phasename       a       b       c       scale   Rwp
blah_001.xye    1       corundum        3       3       12      0.001   3
blah_002.xye    2       corundum        3.1     3.1     12.1    0.002   3.5
blah_003.xye    3       corundum        3.2     3.2     12.2    0.001   3.1
blah_001.xye    2       silcon_NIST     5.4     5.4     5.4     0.002   3
blah_002.xye    3       silcon_NIST     5.41    5.41    5.41    0.004   3.5
blah_003.xye    4       silcon_NIST     5.42    5.42    5.42    0.002   3.1

내 현재 출력은 다음과 같습니다

#filename       seqno   phasename       a       b       c       scale   Rwp
blah_001.xye    1       corundum        3       3       12      0.001   3
blah_002.xye    2       corundum        3.1     3.1     12.1    0.002   3.5
blah_003.xye    3       corundum        3.2     3.2     12.2    0.001   3.1


#filename       seqno   phasename       a       b       c       scale   Rwp
blah_001.xye    2       silcon_NIST     5.4     5.4     5.4     0.002   3
blah_002.xye    3       silcon_NIST     5.41    5.41    5.41    0.004   3.5
blah_003.xye    4       silcon_NIST     5.42    5.42    5.42    0.002   3.1

내가 원하는 출력은 다음과 같습니다.

#filename       seqno   phasename       corundum_a       corundum_b       corundum_c       corundum_scale   corundum_Rwp
blah_001.xye    1       corundum        3       3       12      0.001   3
blah_002.xye    2       corundum        3.1     3.1     12.1    0.002   3.5
blah_003.xye    3       corundum        3.2     3.2     12.2    0.001   3.1


#filename       seqno   phasename       silcon_NIST_a       silcon_NIST_b       silcon_NIST_c       silcon_NIST_scale   silcon_NIST_Rwp
blah_001.xye    2       silcon_NIST     5.4     5.4     5.4     0.002   3
blah_002.xye    3       silcon_NIST     5.41    5.41    5.41    0.004   3.5
blah_003.xye    4       silcon_NIST     5.42    5.42    5.42    0.002   3.1

hdr내가 하고 싶은 일: awk에서 awk 변수를 변경하여 입력 파일에 삽입하기 전에 $i변수의 마지막 네 번째 열에 변수를 추가 하려면 어떻게 해야 합니까?hdr

다른 파일에서 처리하기 위한 다른 예시 헤더

#filename   seqno   phasename   temp    temp_err    csL csL_err csG csG_err strL    strL_err    strG    strG_err    B_Na    B_Na_err    B_Mg    B_Mg_err    B_F B_F_err B_H B_H_err B_O B_O_err B_Fe    B_Fe_err    F_occ   F_occ_err   Na_x    Na_x_err    Na_z    Na_z_err    F1_x    F1_x_err    F1_y    F1_y_err    F1_z    F1_z_err    F2_x    F2_x_err    F2_z    F2_z_err    a1  a1_err  a2  a2_err  a3  a3_err  a4  a4_err  a5  a5_err  a6  a6_err  a7  a7_err  s1  s1_err  s2  s2_err  s3  s3_err  a   a_err   b   b_err   c   c_err   al  al_err  be  be_err  ga  ga_err  volume  volume_err  mass    mass_err    MAC MAC_err density density_err LAC LAC_err Lvol    Lvol_err    e0  e0_err  scale   scale_err   wt% wt%_err num_area    num_area_err    r_bragg r_bragg_err r_wp    r_wp_err    r_exp   r_exp_err   gof gof_err
#filename   seqno   phasename   csL csL_err strG    strG_err    a   a_err   b   b_err   c   c_err   al  al_err  be  be_err  ga  ga_err  volume  volume_err  mass    mass_err    MAC MAC_err density density_err LAC LAC_err Lvol    Lvol_err    e0  e0_err  scale   scale_err   wt% wt%_err num_area    num_area_err    r_bragg r_bragg_err r_wp    r_wp_err    r_exp   r_exp_err   gof gof_err
#filename   seqno   phasename   csG strL    F1_x    F1_y        F1_z    volume      gof 

답변1

$ awk -f script.awk file
#filename       seqno   phasename       corundum_a      corundum_b      corundum_c      corundum_scale  corundum_Rwp
blah_001.xye    1       corundum        3       3       12      0.001   3
blah_002.xye    2       corundum        3.1     3.1     12.1    0.002   3.5
blah_003.xye    3       corundum        3.2     3.2     12.2    0.001   3.1

#filename       seqno   phasename       silcon_NIST_a   silcon_NIST_b   silcon_NIST_c   silcon_NIST_scale       silcon_NIST_Rwp
blah_001.xye    2       silcon_NIST     5.4     5.4     5.4     0.002   3
blah_002.xye    3       silcon_NIST     5.41    5.41    5.41    0.004   3.5
blah_003.xye    4       silcon_NIST     5.42    5.42    5.42    0.002   3.1

script.awk어디

BEGIN   { OFS = "\t" }

/^#/    {
    # save header fields

    for (i = 1; i <= NF; ++i)
        header[i] = $i

    next
}

# if column 2 contains a lower number than the previous line
# (or if no previous line with data), then output header
$2 < col2 || !col2 {
    # output blank line if needed
    if (print_blank) {
        print ""
    }
    print_blank = 1

    # print first three headers as-is
    for (i = 1; i <= 3; ++i)
        printf("%s%s", header[i], OFS)

    # prepend column three to remaining headers
    for (i = 4; i < NF; ++i)
        printf("%s_%s%s", $3, header[i], OFS)
    printf("%s_%s%s", $3, header[NF], ORS)
}

# print all lines and save value from column 2
{ col2 = $2; print }

스크립트는 입력 데이터의 헤더를 배열에 저장합니다 header. 두 번째 열의 값이 이전 행의 두 번째 열 값보다 낮은 경우 데이터를 출력하기 전에 새 헤더를 출력합니다. 첫 번째 제목이 아닌 이상 제목 앞에 빈 줄이 있습니다. 변수 열 이름은 세 번째 필드의 이름에서 가져옵니다.

이 스크립트는 매개변수를 사용하지 않습니다.

답변2

Phase 이름 그룹이 마지막 Phase보다 큰 seqno로 시작될 가능성이 있는 경우 seqno에 의존하지 못할 수도 있지만 Phasename에 의존하는 것이 더 나을 수도 있습니다. Kusalananda가 제안한 적응을 시도해 볼 수도 있습니다.

    awk '
    FNR == 1        {split ($0, header)
                     next
                    }

    $3 != LAST      {printf TMPRS; TMPRS = ORS
                     for (i = 1; i <= NF; ++i) printf ("%s%s%s", (i>3)?$3"_":_, header[i], (i==NF?ORS:OFS))
                    }

                    {LAST = $3
                     print
                    }
    ' OFS="\t" filename1 filename2

관련 정보