2

自分では解決できないテキスト操作の問題があるため、より賢い人の助けが必要です。
私のダミーファイルの例は次のようになります。

Winter    Sally    Additional_text
Winter    Sally    Additional_text
Winter    Nicole    Additional_text  
Spring    Lucy    Additional_text
Spring    Lucy    Additional_text
Spring    Caroline    Additional_text
Spring    Caroline    Additional_text
Summer    Emma    Additional_text
Autumn    Rita    Additional_text
Autumn    Rita    Additional_text
Autumn    Cristina     Additional_text
Autumn    Lucy's_sister     Additional_text
Autumn    Lucy's_sister     Additional_text

私がしたい:
最初の列の項目ごとに、2 番目の列にいくつの異なる名前があるかを数えます。ただし、1) 少なくとも 2 回出現し、かつ 2) 少なくとも 2 つの異なる名前がある (どちらも少なくとも 2 回出現する) という名前だけを数えなければなりません。
次のような出力の場合:

Time    Counts 
Spring    2
Autumn    2

出力の説明:
Winterは 2 つの異なる名前がありますが、Nicole発生するのは 1 回だけです -winter報告されません。
Springは少なくとも 2 つの異なる名前があり、それぞれが少なくとも 2 回出現しSpringます。
1Summerつの名前だけで -Summer報告されていません。
3つの異なる名前がありAutumnますが、少なくとも 2 回出現するのはそのうちの 2 つだけです。RitaLucy's_sister


awk と bash で私のソリューションを 編集します。

cut -d " " -f 1 FILE | sort -u > names
for i in $(cat names)
do 
   grep ^$i FILE | 
   awk '{print $2}' | 
   sort | 
   uniq -c | 
   awk -v VAR="$i" '($1>=2) {print VAR}' | 
   sort | 
   uniq -c | 
   awk '($1>=2) {print $2"\t"$1}' 
done

不器用で繰り返しが多すぎるので、もっと簡単な方法を知りたいです。

4

3 に答える 3

2

これがあなたのために働くはずのawkコマンドです:

awk '{sums[$1"~"$2]++} END {for (a in sums) {split(a, b, "~"); if (sums[a]>1) suma[b[1]]++;}
      for (k in suma) if (suma[k]>1) print k, suma[k]}' inFile
于 2013-06-11T10:55:30.467 に答える
1

を使用する 1 つの方法を次に示しGNU awkます。次のように実行します。

awk -f ./script.awk file

の内容script.awk:

BEGIN {
    OFS="\t"
}
{
    a[$1][ b[$1,$2]++ ]++
}
END {
    print "Time", "Counts";
    for (i in a) {
        for (j in a[i]) {
            if (j >= 1 && a[i][j] >= 2) {
                print i, a[i][j]
            }
        }
    }
}

または、ここにワンライナーがあります:

awk '{ a[$1][ b[$1,$2]++ ]++ } END { print "Time", "Counts"; for (i in a) for (j in a[i]) if (j >= 1 && a[i][j] >= 2) print i, a[i][j] }' OFS="\t" file

結果:

Time    Counts
Autumn  2
Spring  2
于 2013-06-11T11:12:28.147 に答える
1
awk '{kc[$1 "-" $2]++ } 
     END { for (k in kc) { if (kc[k]>=2) {f[gensub("-.*","","g",k)]++}}
           for (kk in f) { if (f[kk]>=2 ) {print kk, f[kk]}}}' INPUTFILE

あなたのために働きます。最初FIRSTCOL-SECONDCOLに、配列内の " " の出現回数をカウントします。次に、ファイルの最後で出現ごとに出現回数をチェックし、それが 1 より大きい場合はFIRSTCOL、別の配列に (キーとして) 格納し、その値に 1 を追加します。次に、すべてFIRSTVALとその値が 1 より大きい場合はその値を出力します。ヘッダーはお任せします。

-:最初の列に' ' があると失敗し

于 2013-06-11T11:04:21.523 に答える