次の.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行ずつ説明:
Perlの実行
,
Fまたはフィールドを読み取る区切り記号ㅏレイ、気をつけて私マイルごとに走るエンディングN電子と金利実装する: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