텍스트 파일에서 중복/역방향 일치 쌍을 제거하고 싶습니다.
예를 들어 파일에는 다음 데이터가 포함되어 있습니다.
10 |Name1 |20 |Name2
20 |Name2 |30 |Name3
20 |Name2 |10 |Name1 <-- Inverse pair (compared to first line) to be removed from text file
40 |Name4 |30 |Name3
나는 다음과 같은 결과를 기대하고 있습니다 :
10 |Name1 |20 |Name2
20 |Name2 |30 |Name3
40 |Name4 |30 |Name3
답변1
awk를 사용하세요:
awk -F '[[:blank:]]*[|][[:blank:]]*' -v SUBSEP='|' '
($1,$2,$3,$4) in seen || ($3,$4,$1,$2) in seen {next}
{seen[$1,$2,$3,$4]; print}
' file
필드 구분 기호를 선택적 선행 또는 후행 공백이 있는 파이프 문자로 설정합니다. 그런 다음 연관 배열 키로서 어느 순서로든 "쌍"을 찾습니다. 발견되면 해당 줄을 건너뛰고, 그렇지 않으면 키가 배열에 추가되고 해당 줄이 인쇄됩니다.
답변2
어쩌면 다음과 같은 것일 수도 있습니다.
perl -F'[|]' -lane '
for (@F) {
# trim the fields to remove leading and trailing blanks
s/^\s+//; s/\s+$//
}
# re-join the trimmed fields into $a
my $a = join "|", @F[0..3];
# same, inverting the two pairs into $b
my $b = join "|", @F[2,3,0,1];
# print unless either $a or $b has been seen before
print unless $seen{$a} || $seen{$b}++' < your-file
%seen
어떤 순서로든 발견된 임의 개수의 쌍을 일반화하려면 쌍을 정렬하여 연관 배열의 키를 형성해야 합니다 .
perl -F'[|]' -lane '
for (@F) {
# trim the fields to remove leading and trailing blanks
s/^\s+//; s/\s+$//
}
my @pairs;
while (my ($a, $b) = splice(@F, 0, 2)) {
push @pairs, "$a|$b"
}
my $key = join "|", sort @pairs;
print unless $seen{$key}++' < your-file
답변3
이를 수행하려면 sed를 사용할 수 있습니다. 아래 코드는 gnu sed를 사용하지만 쉽게 posix와 호환되도록 만들 수 있습니다.
sed -Ee '
$!{
s/$/|/
N
s/[[:blank:]]+//g
H;s/.*//;x;D
}
s/$/|/
G;H;g
y/\n_/_\n/
:xdup
s/_((([^_|]+[|]){2})(([^_|]+[|]){2}))_(.*_)?\4\2_/_\1_\6/
txdup
s/^_//;s/_$//
y/\n_/_\n/
' input.csv
출퇴근 시간이 가까워지면 나중에 설명하겠습니다.
결과:
10|Name1|20|Name2|
20|Name2|30|Name3|
40|Name4|30|Name3|