0

私の問題で私を助けてくれることを願っています。

次のような 3 列のデータを含む入力ファイルがあります。

Apl_No Act_No Sfx_No 
100    10     0
100    11     1
100    12     2
100    13     3
101    20     0
101    21     1

入力のデータと出力の 3 つの追加フィールドを含む出力ファイルを作成する必要があります。次のようになります。

Apl_No Act_No Sfx_No Crt_Act_No Prs_Act_No Cd_Act_No
100    10     0       -         -          -
100    11     1       10        11         12
100    12     2       11        12         13
100    13     3       12        13         10
101    20     0       -         -          -
101    21     1       20        21         20

Everyには、マップされているApl_Noのセットがあります。Act_No3 つの新しいフィールドを作成する必要があります: Crt_Act_No Prs_Act_No Cd_Act_No. 最初の一意が検出されたら、Apl_No列の値 4、5、および 6 ( Crt_Act_No Prs_Act_No Cd_Act_No) をダッシュ​​ アウトする必要があります。Apl_No次のすべての同じの出現についてはCrt_Act_NoAct_No前の行のPrs_Act_Noと同じでありAct_No、現在の行のとCd_Act_No同じでありAct_No、次の行のと同じです。Apl_Noこれは、最後の行を除いて同じものを保持するすべての後続の行に続きます。最後の行では、上記の行と同じ方法で と が入力されますが、最初の一意が検出されたときに最初の行から を取得するCrt_Act_No必要があります。Prs_Act_NoCd_Act_NoAct_NoApl_No

awkを使用してこれを実現したいと考えています。誰でもこれをどうするか教えてください。

4

1 に答える 1

2

1 つの解決策:

awk '
    ## Print header in first line.
    FNR == 1 {
        printf "%s %s %s %s\n", $0, "Crt_Act_No", "Prs_Act_No", "Cd_Act_No";
        next;
    }

    ## If first field not found in the hash means that it is first unique "Apl_No", so
    ## print line with dashes and save some data for use it later.
    ## "line" variable has the content of the previous iteration. Print it if it is set.
    ! apl[ $1 ] {
        if ( line ) {
            sub( /-/, orig_act, line );
            print line;
            line = "";
        }
        printf "%s %s %s %s\n", $0, "-", "-", "-";
        orig_act = prev_act = $2;
        apl[ $1 ] = 1;
        next;
    }

    ## For all non-unique "Apl_No"... 
    {
        ## If it is the first one after the line with
        ## dashes (line not set) save it is content in "line" and the variable
        ## that I will have to check later ("Act_No"). Note that I leave a dash in last
        ## field to substitute in the following iteration.
        if ( ! line ) {
            line = sprintf( "%s %s %s %s", $0, prev_act, $2, "-" );
            prev_act = $2;
            next;
        }

        ## Now I know the field, so substitute the dash with it, print and repeat
        ## the process with current line.
        sub( /-/, $2, line );
        print line;
        line = sprintf( "%s %s %s %s", $0, prev_act, $2, "-" );
        prev_act = $2;
    }
    END {
        if ( line ) {
            sub( /-/, orig_act, line );
            print line;
        }        
    }
' infile | column -t

これにより、次の結果が得られます。

Apl_No  Act_No  Sfx_No  Crt_Act_No  Prs_Act_No  Cd_Act_No
100     10      0       -           -           -
100     11      1       10          11          12
100     12      2       11          12          13
100     13      3       12          13          10
101     20      0       -           -           -
101     21      1       20          21          20
于 2012-10-04T20:59:18.150 に答える