最初の列と一致する行の場合は、2番目の列を使用して「X参照Y」リストを作成します。

最初の列と一致する行の場合は、2番目の列を使用して「X参照Y」リストを作成します。

ウィキデータの場合は、QuickStatmentsを作成して同じ名前の要塞にP1889値を割り当てたいと思います。これは次のように単純化できます。

次の内容を含むファイルの場合:

Fort George,Q12
Fort George,Q56
Fort George,Q678
Fort Anne,Q3

最初の列で正確な一致を実行し、XがYを見るときに一致するすべてのペアを出力したいと思います。

Q12 see also Q56
Q12 see also Q678
Q56 see also Q12
Q56 see also Q678
Q678 see also Q12
Q678 see also Q56

ファイルは最初の列に基づいてソートされます。これは何か奇妙な問題のように感じますが、執筆をあきらめました。

ベストアンサー1

使用ミラーmlr)は最初に最初のフィールドに基づいて2番目のフィールドを縮小し(実際にはソートする必要はありません)、縮小された2番目のフィールドを繰り返して文字列の組み合わせを印刷します。

$ mlr --csv -N nest --ivar : -f 2 then put -q 'a = splita($2, ":"); for (i in a) { for (j in a) { i != j { print i . " see also " . j } } }' file
Q12 see also Q56
Q12 see also Q678
Q56 see also Q12
Q56 see also Q678
Q678 see also Q12
Q678 see also Q56

実行後の中間結果はnest次のとおりです。

$ mlr --csv -N nest --ivar : -f 2 file
Fort George,Q12:Q56:Q678
Fort Anne,Q3

このput表現は美しいです。

a = splita($2, ":");

for (i in a) {
    for (j in a) {
        i != j { print i . " see also " . j }
    }
}

同じパターンに従うことができますが、awkまず入力が次のようになると仮定する必要があります。シンプルCSV(つまり、挿入されたカンマや改行などを含まない)はさらに冗長になります。

$ awk -F , '{ d[$1] = d[$1] == "" ? $2 : d[$1] ":" $2 } END { for (k in d) { split(d[k],a,":"); for (i in a) for (j in a) if (i != j) printf "%s see also %s\n", a[i], a[j] } }' file
Q56 see also Q678
Q56 see also Q12
Q678 see also Q56
Q678 see also Q12
Q12 see also Q56
Q12 see also Q678

コードがawk美しく印刷されます。

{
    d[$1] = d[$1] == "" ? $2 : d[$1] ":" $2
}

END {
    for (k in d) {
        split(d[k], a, ":")

        for (i in a) for (j in a)
            if (i != j) printf "%s see also %s\n", a[i], a[j]
    }
}

in連想配列のインデックスにアクセスするためにinを使用しても、特定のawk順序が保証されるわけではありません。順序を変更するには、代わりに算術ループを使用してください。内容が長すぎてここではお見せしません。

おすすめ記事