匹配 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

换句话说,我希望获得第三列中记录的每个值该对出现的次数,以及同一值出现的A,B次数。B,A

我主要是在努力将所说的行A,B与所说的行相匹配B,A

非常感谢对此的任何帮助。

答案1

GNUawk解决方案:

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. 运行 Perl, F或分隔符,将字段读入A雷,照顾一个结局,跑每一里ne 和e执行:

    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

相关内容