我有一个 .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
逐行解释:
运行 Perl
,
F或分隔符,将字段读入A雷,照顾我一个结局,跑每一里ne 和e执行: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
是输入文件。
因此,对于此输入数据:
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