CSVファイルの可逆ペアの一致

CSVファイルの可逆ペアの一致

次の.csvファイルがあります。

A,B,1999
C,D,1990
B,A,1989
D,A,1990
A,B,1999
...

おおよそ次のように再び整理したいと思います。

A,B,1989,0,B,A,1
A,B,1999,2,B,A,0
C,D,1990,1,D,C,0
D,A,1990,1,A,D,0

つまり、3番目の列に記録された各値について、対応するペアの発生回数とA,B同じ値の発生回数を取得したいと思います。B,A

私は主にその行をA,Bその行と一致させようとしていますB,A

これにご協力いただきありがとうございます。

答え1

牛に似た一種の栄養awk解決策:

awk -F',' '{ k=$1 FS $2 }{ a[k][$3]++; rev[k]=$2 FS $1 }
           END{ 
               for(i in a) 
                   for(j in a[i]) { 
                       print i, j, a[i][j], rev[i], a[rev[i]][j]+0; 
                       delete a[rev[i]][j] 
                   }
           }' OFS=',' file

出力:

C,D,1990,1,D,C,0
A,B,1999,2,B,A,0
D,A,1990,1,A,D,0
B,A,1989,1,A,B,0

答え2

これはPerlで動作するようです。

perl -F, -alne '
    next if /^\s*$/;
    $hs{$F[2]}{"$F[0],$F[1]"}++;
    END{
        while (my ($nr, $lhs) = each %hs) {
            while (my ($lts, $cnt) = each %{$lhs}) {
                my $rvs = scalar reverse $lts;
                my $rvsn = $hs{$nr}{$rvs} // 0;
                print "$lts,$nr,$cnt,$rvs,$rvsn";
                delete $hs{$nr}{$rvs};
            }
        }
    }
' data

1行ずつ説明:

  1. Perlの実行, Fまたはフィールドを読み取る区切り記号レイ、気をつけてマイルごとに走るエンディングN電子と金利実装する:

    perl -F, -alne '
    
  2. 入力時に空白行をスキップします。

    next if /^\s*$/;
    
  3. 各レコードのハッシュカウンタをインクリメントします。

    $hs{$F[2]}{"$F[0],$F[1]"}++;
    
  4. 最後のブロックを開始します。

    END{
    
  5. ハッシュ値を読み込みます。

    while (my ($nr, $lhs) = each %hs) {
        while (my ($lts, $cnt) = each %{$lhs}) {
    
  6. 印刷するデータの準備:

    my $rvs = scalar reverse $lts;
    my $rvsn = $hs{$nr}{$rvs} // 0;
    print "$lts,$nr,$cnt,$rvs,$rvsn";
    
  7. ハッシュからペアエントリを削除します。

    delete $hs{$nr}{$rvs};
    
  8. data入力ファイルです。

したがって、この入力データの場合:

A,B,1999
C,D,1990
B,A,1989
D,A,1990
A,B,1999
B,A,1999

次の結果を出力する必要があります。

D,A,1990,1,A,D,0
C,D,1990,1,D,C,0
B,A,1989,1,A,B,0
A,B,1999,2,B,A,1

関連情報