スプレッドシートの2つの列に基づいて一意の値の数をカウントする必要があります。
ファイルが次のようになり、名前、姓、会社の順になっていると仮定します。
joe allen ibm
joe smith ibm
joe allen google
joe smith google
rachel allen google
そして、姓を無視しながら、各会社の一意の名の数を数える必要があります。
joe ibm 2
joe google 2
rachel google 1
私はこのコードを持っています:
sort file.tsv | uniq -ci | awk '{print $2,$1}'
姓の列を削除するだけで、そのコードは機能します。しかし、その列を削除したくない場合は、awkにそれを無視させ、出力を新しいファイルに保存するだけですか?
データはタブで区切られています\t
2次元配列 を使用したGNU awkソリューション
gawk -F $'\t' '{a[$1][$3]++} END {for (i in a) for (j in a[i]) print i, j, a[i][j]}' foo.txt
a[$1][$3]++
名と姓の各組み合わせに対して、カウントをインクリメントします古い形式の多次元配列を使用して他のawk
sを機能させる別の方法:
awk -F $'\t' '{a[$1, $3]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
SUBSEP
で区切られたインデックスの連結を使用するため、元のインデックスを取得するにはSUBSEP
で分割する必要があります。Counter
モジュールのcollections
クラスを使用するPythonicソリューションは、イテラブルの各要素の出現回数をカウントします。
#!/usr/bin/env python2
import collections
with open('file.txt') as f:
names = []
for line in f:
names.append(line.strip().split()[0] + ' ' + line.strip().split()[2])
result_dict = collections.Counter(names)
for person in result_dict:
print person + ' ' + str(result_dict[person])
cut
を使用して、最初に操作する列を選択できます。したがって、列はスペースで区切られ、FNAME SNAME COMPANYであるため、使用できる列1および3のみが必要です。
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
これは、cut
に、区切り文字として単一のスペース ''を使用して分離し、列1と3をソートに渡すように指示します。
次のような出力が生成されます。
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
2 joe google
2 joe ibm
1 rachel google
次のPerl onelinerは、データを抽出します。
Perl -e '/(.*)\t.*\t(.*)/ and $a{"$1 $2"}++ for (<>); print "$_ $a{$_}\n" foreach (keys%a);' file.tsv
出力:
joe ibm 2
joe google 2
rachel google 1