행당 레코드만 있는 대형 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
반복되는 라인을 덮어쓰는 패턴 공간의 끝에 플래그가 배치됩니다. 따라서 플래그가 패턴 공간의 시작 부분에 버블링되면 => 작업이 종료되고 이제 패턴 공간에서 플래그를 제거하고 stdout으로 인쇄할 수 있습니다.
$ 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