csvファイルから一意の単語数を取得する方法はありますか?

csvファイルから一意の単語数を取得する方法はありますか?

次の内容を含むテキストファイルがあります。

Notes1,Notes2,Id3,Id4
I'd like to play tennis with you some day with everyone,Mary enjoys cooking,id1234,5678
Some of my friends can speak English well and turkish well,She likes bananas,id3456,9898

最終出力は次のようになります。

word, iterationcount,id3,id4,columnname
I'd , 1, id1234,5678,Notes1
like, 1, id1234,5678,Notes1
with, 2, id1234,5678,Notes1 .... 

some, 1, id3456,9898,Notes2
well, 2, id3456,9898,Notes2

列1の各単語と列2の同じ出力について、対応する数はId3、Id4のグループ化に基づいています。

私は次のようにいくつかのアプローチを試しました

awk -F, '{for (i=1; i<=NF-1; i++) words[$1","$2][$i]+=1} END {for (i in words) {for (word in words[i]) {print word "," words[i][word]}}} ' file.csv


awk -F, '{count[$2","$3]+=(NF-1); for (i=1; i<=NF-1; i++) words[$2","$3][$i]+=1} END {for (i in count) {for (word in words[i]) {print i, word, words[i][word]}}} ' file.csv | sort

何か抜けましたね。誰でも提案できますか?

ベストアンサー1

GNU awk(質問に投稿したコードと通常はLinuxのawkバリアントを考慮してすでに使用しています)FPATと配列配列を使用します。

$ cat tst.awk
BEGIN {
    OFS = ","
    FPAT = "([^" OFS "]*)|(\"([^\"]|\"\")*\")"
}
NR == 1 {
    for ( i=1; i<=NF; i++ ) {
        fldName[i] = $i
    }
    next
}
{
    analyze(1)
    analyze(2)
}

function analyze(fldNr,     words,i,word,cnt,key,out) {
    out = "out" fldNr
    split($fldNr,words)
    for ( i in words ) {
        word = words[i]
        cnt[$3 OFS $4 OFS fldName[fldNr]][word]++
    }
    if ( !doneHdr[fldNr]++ ) {
        print "word", "iterationcount", "id3", "id4", "columnname" > out
    }
    for ( key in cnt ) {
        for ( word in cnt[key] ) {
            print word, cnt[key][word], key > out
        }
    }
}

$ awk -f tst.awk file.csv

$ head -100 out?
==> out1 <==
word,iterationcount,id3,id4,columnname
some,1,id1234,5678,Notes1
you,1,id1234,5678,Notes1
with,2,id1234,5678,Notes1
day,1,id1234,5678,Notes1
everyone,1,id1234,5678,Notes1
tennis,1,id1234,5678,Notes1
to,1,id1234,5678,Notes1
play,1,id1234,5678,Notes1
I'd,1,id1234,5678,Notes1
like,1,id1234,5678,Notes1
can,1,id3456,9898,Notes1
friends,1,id3456,9898,Notes1
well,2,id3456,9898,Notes1
Some,1,id3456,9898,Notes1
of,1,id3456,9898,Notes1
and,1,id3456,9898,Notes1
speak,1,id3456,9898,Notes1
my,1,id3456,9898,Notes1
turkish,1,id3456,9898,Notes1
English,1,id3456,9898,Notes1

==> out2 <==
word,iterationcount,id3,id4,columnname
cooking,1,id1234,5678,Notes2
Mary,1,id1234,5678,Notes2
enjoys,1,id1234,5678,Notes2
likes,1,id3456,9898,Notes2
bananas,1,id3456,9898,Notes2
She,1,id3456,9898,Notes2

上記は、フィールドにカンマが含まれている場合は二重引用符で囲まれ、引用符付きフィールドに二重引用符が含まれている場合は2倍にエスケープされていると想定しています。RFC 4180

また、どのフィールドにも改行文字を含めることはできないと仮定します。それらのどれも見ることができればawkを使用してcsvを効率的に解析する最も強力な方法は何ですかこれを処理するために何をすべきかをご覧ください。

おすすめ記事