ご協力ありがとうございます。データファイルから情報を抽出していますが、場合によってはサイズが1TBを超えています。
- 各行の変数はスペースで区切られます。
- ファイルごとの1行あたりの変数数は固定です。
- 右側の3列は常に自然数です。
- 行は常に配列で始まります
- 配列には常にファイルごとに固定数の要素が含まれます。
- 配列には1〜5個の要素を含めることができます。
- ソースデータファイルが正しくソートされました。
次の例では、並列処理を使用するときに3つの要素を持つ配列をファイルまたはブロック内の他のすべての配列と比較します。配列が一致したら、右から2番目の列を追加して行をマージします。一番右の列と-2列が更新されます。
g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | head
Z'Z . _END_ 1840 1 1
Z'Z . _END_ 1847 1 1
Z'Z . _END_ 1850 1 1
Z'Z . _END_ 1855 1 1
Z'Z . _END_ 1856 1 1
Z'Z . _END_ 1857 1 1
Z'Z . _END_ 1860 1 1
Z'Z . _END_ 1863 1 1
Z'Z . _END_ 1865 1 1
Z'Z . _END_ 1869 1 1
g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | parallel -k -q --pipe awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}' | head
Zz_NOUN _NOUN_ , 98
zz _._ _PRT_ 120
ZZ or_CONJ _NOUN_ 122
ZZ_NOUN _DET_ _VERB_ 59
zz_DET _NOUN_ . 86
ZZ is_VERB reached 42
ZZ_NUM ^ ^ 65
ZZ _NOUN_ _VERB_ 3163
ZZ ,_. " 52
ZZ / _NUM_ 275
例では、3つの要素を持つ配列を説明していますが、1〜5個の要素を含む配列を使用しています。
awk '{a[$1] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$4] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$3" "$5] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awkにファイルまたはブロックのすべての配列とすべての配列を一致させる代わりに、awkに現在の配列を前の行の以前の配列と比較するように指示するにはどうすればよいですか?
ありがとう
サンプルソースファイル。
wget --show-progress -cq http://storage.googleapis.com/books/ngrams/books/googlebooks-eng-us-all-3gram-20120701-zz.gz -O - | zcat
ベストアンサー1
コメントにURLとして提供される入力データはタブで区切られます。これは、タブで区切られた最初のフィールドを一種の「キー」で解析して他の行と比較できることを意味します。実際、私たちはいいえ最初のフィールドのスペースで区切られた単語に注意する必要がありますが、最初のフィールド全体を単一のエンティティとして扱うことができます。
BEGIN { OFS = FS = "\t" }
{
count = $(NF - 1)
key = $1
}
key != previous {
if (previous != "")
print previous, sum
sum = 0
}
{
sum += count
previous = key
}
END {
if (previous != "")
print previous, sum
}
プログラムawk
は「count」フィールド(2番目のフィールド)を解析し、count
後で前の行のキーと比較できるように最初のフィールドを「キー」として使用します。これは、このブロックBEGIN
(入力と出力の区切り記号のみを設定)の後の最初のブロックです。
キーが前の行のキーと異なる場合、これは別の単語セットを見ていることを意味します。前の行のキーと合計を出力し、合計をリセットします。
すべての行について、その行の数に合計を追加して更新しますprevious
(今行が完了したので、key
次の行になりますprevious
)。
最後に、データの最後の行情報を出力します。
を使用して実行できますawk -f script.awk inputfile
。
「一行」で:
awk -F '\t' 'BEGIN{OFS=FS} {c=$(NF-1);k=$1} k!=p {if(p!="")print p,s;s=0} {s+=c;p=k} END {if(p!="") print p,s}' file