두 열에서 이와 같은 쌍별 비교를 수행하는 상황에서 중복성을 제거하는 *NIX 방법은 무엇입니까?
A B
B A
A C
A D
C A
D A
B C
C B
A B
동일한 비교를 나타내기 위해 B A
데이터세트에서 이러한 중복성을 제거하고 싶습니다. 최종 결과는
A B
A C
A D
B C
답변1
doit ()
{
awk '{
key=$1<=$2? $1 FS $2 : $2 FS $1;
if (!seen[key]) print $1,$2
seen[key]=1
}'
}
$ doit <test
A B
A C
A D
B C
$
(또는 Kristang의 답변이 너무 친절하기 때문에 더 간결하게 말하면)
awk '!seen[$1<=$2? $1 FS $2: $2 FS $1]++ {print $1,$2}'
데이터의 공백에 신경 쓰지 않는다면 더 줄일 수 있습니다.
awk '!seen[$1<=$2? $1 FS $2: $2 FS $1]++'
)
이는 FS
awk의 "필드 구분자" 변수로, 여기서는 키 필드 사이의 경계가 올바르게 식별되도록 하기 위해 사용됩니다. 내 원본에서는 함께 실행되었으며 $1$2
Stephane Chazelas가 지적한 대로 A BC
및 AB C
복제본으로 처리됩니다.
답변2
펄에서는:
perl -lane 'print if !$seen{join(" ", sort @F)}++'
이는 필드를 정렬하고 연결하여("CA"가 키 "AC"가 됨) 에 추가함으로써 수행됩니다 $seen
. 왜냐하면 조건절은 참인 경우에만 0으로 평가되기 때문입니다. 증분 후에는 이 비교가 처음 발생할 때만 발생합니다.
답변3
고유한 행의 요소 순서를 유지해도 괜찮다면 각 행을 정렬한 다음 행을 정렬하고 중복 항목을 제거할 수 있습니다.
awk '{ if ($2 < $1) print $2, $1; else print $1, $2; }' | sort -u