AWKと配列 - より具体的な例

AWKと配列 - より具体的な例

私の入力データファイルは次のとおりです

Town,Code1,Code2,Code3,Code4
Oxford,X532,X011,X989
Oxford,X532,X011
Hendon,X002,X011,X222,X769

以下の関連コードを含む都市を一覧表示するには、出力が必要です。

Oxford,X532,1,Prim
Oxford,X011,2,Secd
Oxford,X989,3,Secd
Oxford,X532,1,Prim
Oxford,X001,2,Secd
Hendon,X002,1,Prim
Hendon,X011,2,Secd
Hendon,X222,3,Secd
Hendon,X769,4,Secd

しかし、同じ場所に現れるコードを要約するためにも必要なので、上記は次のとおりです。

Oxford,X532,1,Prim,2
Oxford,X011,2,Secd,2
Oxford,X989,3,Secd,1
Oxford,X532,1,Prim,2
Oxford,X001,2,Secd,1
Hendon,X002,1,Prim,1
Hendon,X011,2,Secd,1
Hendon,X222,3,Secd,1
Hendon,X769,4,Secd,1

現在私が書いたAWKは私が望むほとんどのことを行いますが、明らかに出力で同じコードが同じ場所に存在する場所の数を格納する配列を作成する必要があります。私のAWKは次のとおりです。

FS=","
OFS=","
}
{ 

site=$1
code[1]=$2
code[2]=$3
code[3]=$4
code[4]=$5

key=site

for (i=1; i<=4; ++i)    {
        cnt=i
        ++recs[i]
        posn=""
        if (cnt==1)     {posn="Prim"}
        else            {posn="Secd"}

        if (code[i] !="")       {print key,code[i], cnt, posn}
                        }

}

正しい出力を生成するためにAWKを使用してこれをどのように実行できますか? END部分などが必要かどうかは不明です。

答え1

この試み、

awk -F ',' '{for (i=2;i<=NF;i++) { if (i==2) {print $1","$i","i-1",""Prim"}  else print $1","$i","i-1",""Secd"}}' file
Oxford,X532,1,Prim
Oxford,X011,2,Secd
Oxford,X989,3,Secd
Oxford,X532,1,Prim
Oxford,X001,2,Secd
Hendon,X002,1,Prim
Hendon,X011,2,Secd
Hendon,X222,3,Secd
Hendon,X769,4,Secd

同じ場所に表示されるコードをまとめてみてください。

ARRAY=(`awk -F ',' '{for (i=2;i<=NF;i++) { if (i==2) {print $1","$i","i-1",""Prim"}  else print $1","$i","i-1",""Secd"}}' file`)
for i in ${ARRAY[@]}
do
    PATTERN=`echo $i | awk -F ',' '{print $2}'`
    COUNT=`echo "${ARRAY[@]}"| tr ' ' '\n' | grep -c $PATTERN `
    echo "$i,$COUNT"
done

Oxford,X532,1,Prim,2
Oxford,X011,2,Secd,2
Oxford,X989,3,Secd,1
Oxford,X532,1,Prim,2
Oxford,X001,2,Secd,1
Hendon,X002,1,Prim,1
Hendon,X011,2,Secd,2
Hendon,X222,3,Secd,1
Hendon,X769,4,Secd,1

答え2

入力ファイルを2回処理します。一度は村とコードペアの発生回数を計算し、一度はレポートを出力します。

awk -F, -v OFS=, '
    FNR == 1 {next}
    NR == FNR {
        for (i=2; i <= NF; i++)
            count[$1,$i]++
        next
    }
    {
        for (i=2; i <= NF; i++)
            print $1, \
                  $i, \
                  (i-1), \
                  (i == 2 ? "Prim" : "Secd"), \
                  count[$1,$i]
    }
' file file
Oxford,X532,1,Prim,2
Oxford,X011,2,Secd,2
Oxford,X989,3,Secd,1
Oxford,X532,1,Prim,2
Oxford,X011,2,Secd,2
Hendon,X002,1,Prim,1
Hendon,X011,2,Secd,1
Hendon,X222,3,Secd,1
Hendon,X769,4,Secd,1

答え3

BEGIN { 
    FS=","
    OFS=","
}
{
    site=$1
    code[1]=$2
    code[2]=$3
    code[3]=$4
    code[4]=$5    
    key=site

    for (i=1; i<=4; ++i)    {

        cnt=i
        ++recs[i]
        posn=""
        if (cnt==1)     {posn="Prim"}
        else            {posn="Secd"}

        if (code[i] !="")       { myarr[key","code[i]"," posn]++}
                        }
}
END{
    for (i in myarr) {print i","myarr[i]}
}

結果:

Hendon,X002,Prim,1
Hendon,X769,Secd,1
Oxford,X011,Secd,2
Hendon,X222,Secd,1
Oxford,X532,Prim,2
Hendon,X011,Secd,1
Oxford,X989,Secd,1

関連情報