データの例を以下に示します。最初の2つの列はIDで、3番目の列は頻度です。
1 2 99
2 3 62
4 5 80
4 4 98
5 5 79
6 1 98
最初と2番目の列は、同一のIDまたは重複したIDです。たとえば、1、2、3、6は同じ人です。 1==2、2==3などなので、1==3です。したがって、データをこのように分割できます。
人1
1 2 99
2 3 62
6 1 98
人2
4 5 80
4 4 98
5 5 79
上記のようにデータをどのように分割できますか?ここでは、行全体を比較する必要があります。これは私にとって混乱した部分です。次に、各グループ内の3番目の列の頻度に基づいてIDを選択したいと思います。ここでは、他のファイルからこれらのIDを削除するために最も頻度の低い動物を取得します。推奨される最終出力は次のとおりです。
2 3 62
6 1 98
4 5 80
5 5 79
私は答えを探していますが、私にとっては複雑に見えます。たぶん、データを分割するよりも良い方法があるかもしれません。どんなアイデアでもお願いします。
ベストアンサー1
最初の質問を解決するには、すべてのUnixシステムのbourne派生シェルでawk + sortを使用して入力を分割する方法は次のとおりです(私はshebangでbashを使用しますが、bashである必要はありません)。
$ cat tst.sh
#!/usr/bin/env bash
awk '{ print $0 ORS $2, $1, $3 }' "${@:--}" |
sort -n -k1,1 -k2,2 |
awk '
!seen[($1 > $2 ? $1 FS $2 : $2 FS $1)]++ {
out = ""
for ( i=1; i<=2; i++ ) {
if ( $i in map ) {
out = map[$i]
break
}
}
if ( out == "" ) {
out = "person_" (++numPeople)
}
for ( i=1; i<=2; i++ ) {
map[$i] = out
}
print >> out
close(out)
}
'
次の行を含むように公開した入力例を変更する必要があります。私のコメント分割が機能していることを実際にテストするには、次の手順を実行します。
$ cat file
1 2 99
2 3 62
4 5 80
4 4 98
5 5 79
6 1 98
7 8 99
9 10 98
9 7 97
$ ./tst.sh file
$ head person*
==> person_1 <==
1 2 99
1 6 98
2 3 62
==> person_2 <==
4 4 98
4 5 80
5 5 79
==> person_3 <==
7 8 99
7 9 97
9 10 98
1 2 x
上記はと同じであるため、各行の最初の2つのIDの順序は重要ではないと仮定します2 1 x
。