큰 CSV 파일에서 중복 ID를 찾으려고 하는데 한 줄에 레코드가 있지만 중복을 찾는 조건은 첫 번째 열이 됩니다.<id>,<value>,<date>
예제.csv
11111111,high,6/3/2019
22222222,high,6/3/2019
33333333,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019
원하는 출력:
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019
출력에는 순서가 필요하지 않습니다.
답변1
AWK 사용:
awk -F, 'data[$1] && !output[$1] { print data[$1]; output[$1] = 1 }; output[$1]; { data[$1] = $0 }'
이는 모든 행을 살펴보고 다음과 같이 작동합니다.
- 첫 번째 열의 값을 이미 본 경우 해당 값과 일치하는 줄을 출력하고 기억된 줄을 출력해야 합니다.
- 첫 번째 열이 출력하려는 열과 일치하면 현재 줄을 출력합니다.
- 첫 번째 열에 키가 지정된 현재 줄을 저장합니다.
답변2
모든 ID의 길이가 같은 경우(예제에서는 8자) sort
및 GNU를 사용하여 모든 작업을 수행할 수 있습니다 uniq
.
$ sort file | uniq -Dw 8
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019
길이가 같지 않은 경우에도 이 접근 방식을 사용할 수 있지만 좀 더 복잡해집니다.
$ tr ',' ' ' < file | sort | rev | uniq -f2 -D | rev | tr ' ' ','
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019
답변3
awk -F, '$1 in m { print m[$1]$0; m[$1]=""; next }
{ m[$1]=$0 "\n" }' ex
답변4
GNU sed
이는 확장된 정규식 구성을 사용하여 수행할 수 있습니다 . 먼저 패턴 공간에 파일을 로드한 다음 패턴 공간의 시작 부분에서 반복되지 않는 줄을 제거합니다. 또한 \n\n
패턴 공간의 끝에 플래그 가 배치되어 반복되는 라인을 던지게 됩니다. 따라서 이 플래그가 패턴 공간의 시작 부분까지 버블링되면 => 작업이 끝났으며 이제 패턴 공간에서 마커를 제거하고 표준 출력으로 인쇄할 수 있습니다.
$ sed -Ee '
$!{
N;s/^/\n/
$s/$/\n\n/;D
}
/^([^,\n]*),[^\n]*\n(.*\n)?\1,/!D
s/^([^\n]*)(.*)/\2\1\n/;/^\n\n/!D
s/^\n\n//;s/\n$//
' inp
이것은 POSIX-sed
패턴이나 홀드 공간 중 어느 시점에서도 전체 파일을 유지하지 않는 문제에 접근하는 버전이자 또 다른 방법입니다. 중복된 줄이 보이자마자 표준 출력으로 인쇄되고 참조 줄이 표시되어 인쇄됩니다. 다음에 중복된 줄이 보일 때 인쇄하고 싶지 않기 때문에 표시됩니다.
$ sed -ne '
H;g;y/\n_/_\n/
/.*_\([^,_]*\)\(,[^_]*\)\[0]_\(.*_\)\{0,1\}\1,[^_]*$/{
s//\1\2/;y/_\n/\n_/;p
g;s/.*\n//p;g;y/\n_/_\n/
s/\(.*_\([^,_]*\),[^_]*\)\[0]\(_\(.*_\)\{0,1\}\)\2,[^_]*$/\1[1]\3/
s/_$//;y/_\n/\n_/;bh
}
/.*_\([^,_]*\)\(,[^_]*\)\[1]_\(.*_\)\{0,1\}\1,[^_]*$/{
s/.*_//;y/_\n/\n_/;p
g;s/\(.*\)\n.*/\1/;bh
}
y/_\n/\n_/;s/$/[0]/;:h;h
' inp
이는 Perl
배열 해시에서 라인을 유지하는 문제에 대한 기반 솔루션입니다. 반복되는 줄이 보이자마자 배열을 인쇄하고 비우고 중복된 줄도 인쇄합니다.
$ perl -F, -lane '
push(@{$h{$F[0]}},$_),next if ! exists $h{$F[0]};
print for splice(@{$h{$F[0]}}),$_;
' inp
산출:
11111111,high,6/3/2019
11111111,low,5/3/2019
11111111,medium,7/3/2019