내 데이터 세트는 다음과 같습니다.
col1,col2,col3
a,b,c
a,d,f
d,u,v
f,g,h
d,u,g
x,t,k
예상 출력:
f,g,h
x,t,k
선택 기준:
여러 번 문제가 발생하면 col1
관련 행이 모두 삭제됩니다.
sort
Linux 나 uniq
다른 것을 사용하여 문제를 해결할 수 있습니까 ?
답변1
다음은 "비버퍼링" (1) 2단계 접근 방식 입니다 awk
(일반 파일에서만 작동함).
awk -F',' 'NR==FNR{cnt[$1]++;next} FNR>1&&cnt[$1]==1' input.csv input.csv
이렇게 하면 파일이 두 번 처리되므로 명령줄에서 인수로 두 번 지정됩니다.
- 인수는
-F','
필드 구분 기호를 로 설정합니다,
. - 첫 번째 단계에서
NR
전역 라인 카운터인 가FNR
파일별 라인 카운터인 와 같을 때 열 1의 각 값이 배열cnt
(값을 "배열 인덱스"로 사용)에서 발견되는 빈도를 등록합니다. 하지만 즉시 다음 줄로 처리를 건너뜁니다. - 두 번째 패스에서는 첫 번째 열의 현재 값에 대한 발생 카운터가 정확히 1이고 파일 내의 줄 번호가 1보다 큰지(헤더를 건너뛰기 위해) 확인합니다. 그것이 참인 경우에만 현재 줄이 인쇄됩니다. 이는 현재 행을 인쇄하도록
awk
평가하는 규칙 블록 외부의 표현식이 지시하는 구문을true
사용 합니다 .awk
(1) 내가 남긴 댓글에 대한 반응비버퍼링왜냐하면 솔루션이 파일의 일부 데이터를 임시로 RAM에 저장하기 때문입니다.하다RAM 사용량과 함께 제공됩니다. 그러나 파일 내용을 그대로 저장하지는 않습니다.게다가RAM에 있는 다른 스크롤 유지 데이터(나실제 의미에서 "버퍼링"을 고려합니다).
답변2
파일이 /tmp/data
Perl one-liner로 수행할 수 있다고 가정합니다.
perl -e 'while(<STDIN>) { /(^\S+?),/; $show->{$1}=$_; $count->{$1}++;}; foreach(keys %$show) {print $show->{$_} if($count->{$_} == 1);}' < /tmp/data
또는 더 읽기 쉽습니다... :
while(<STDIN>) { #loop through all lines in the input and put the lines in "$_"
/(^\S+?),/; #Everything before the first "," now ends up in "$1"
$show->{$1} = $_; #a hash will be created with as keys the "$1" and as values the "$_"
$count->{$1}++; #In the hash $count the number of occurrences will be increased everytime the same $1 appears
}
foreach(keys %$show) { #loop trough all lines
print $show->{$_} if($count->{$_} == 1); #only print them if they occur once
}
답변3
awk
유일한 솔루션
질서를 지키지 않음
awk -F, 'NR>1 { count[$1]++ ; line[$1]=$0 ;} END { for ( c in count) if (count[c] ==1) print line[c]}' data
질서 유지
awk -F, 'NR>1 { row[a]=$0; col[a]=$1; count[$1]++; ++a; } END { for (i=0; i<a; ++i) if (count[col[i]]==1) print row[i]; }' data
어디
-F,
,
awk에게 구분 기호로 사용하라고 지시하세요.NR>1
첫 번째 줄 이후count[$1]++
첫 번째 열의 개수 요소line[$1]=$0
매장 라인END
파일 끝 이후for ( c in count)
요소를 통해 루프if (count[c] ==1)
하나만 있다면print line[c]
인쇄 라인a
col[]
변형을 보존하기 위해 라인 순서를 저장하는 데 사용됩니다 .
이것은 한 줄로 작성할 수 있습니다. 가독성을 위해 접습니다.
답변4
필수 POSIX 도구의 모든 버전과 입력의 모든 문자를 사용하여 장식/정렬/사용/장식 해제(입력이 실제로 쉼표 및/또는 줄 바꿈을 포함할 수 있는 인용 필드가 있는 CSV가 아닌 경우 다른 모든 답변도 실패함) 및 출력에 대한 입력 줄의 순서를 유지하고 입력을 한 번만 열면 입력이 파이프나 파일에서 오는 경우 전체 입력을 메모리에 저장하지 않고도 작동합니다.
$ awk 'BEGIN{FS=OFS=","} NR>1{print ++cnt[$1], NR, $0}' file |
sort -nt, -k1,1r -k2,2 |
awk -F, '(!seen[$3]++) && ($1==1)' |
cut -d, -f3-
f,g,h
x,t,k