
다음과 같은 .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
암소 비슷한 일종의 영양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
한 줄씩 설명:
펄 실행
,
에프또는 필드를 읽을 구분 기호ㅏ레이, 조심해나마일마다 달리는 엔딩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