중복 항목 찾기 및 바꾸기

중복 항목 찾기 및 바꾸기

다음과 같이 연결된 이메일이 포함된 파일이 있습니다.

id  emails
1   [email protected]
2   [email protected]
3   [email protected],[email protected],[email protected]

각 행에는 서로 다른 이메일만 있지만 위의 1행과 3행에 표시된 것처럼 한 행에서 다른 행으로 중복이 있을 수 있습니다. 파일이 다음과 같이 보이도록 파일에서 중복 항목을 제거해야 합니다.

id  emails
1   [email protected]
2   [email protected]
3   [email protected],[email protected]

이는 각 줄과 그 뒤의 모든 줄을 확인해야 함을 의미합니다. 내가 가지고 있는 데이터의 양을 고려하면 어떤 종류의 반복 스크립트에서도 이는 가능하지 않습니다. 나는 이것을 달성할 수 있는 간단한(또는 적어도 실행 가능한) 방법이 있다고 생각합니다.또는sed하지만 아직 찾지 못했습니다.

답변1

다음은 정확한 입력 형식에 작동하고 빠르게 실행되는 sed 솔루션입니다.

sed -rz 's:[ \t]+:,:g;s:$:,:mg;:l;s:,([^,]+),(.*),\1,:,\1,\2,:;tl;s:,$::mg;s:^([^,]+),:\1\t:mg' file.csv

작동 방식:

"-z" 플래그는 전체 파일을 로드하므로 다음 코드는 기본값처럼 모든 줄에 적용되는 대신 한 번만 적용됩니다.

#transform input format to actual CSV format
s:[ \t]+:,:g;s:$:,:mg;
#loop while the s command can still find and replace
:l;
    #main code: find two identical cell values anywhere and delete the latter
    #on a very big file this can suffer from backtracking nightmare
    s:,([^,]+),(.*),\1,:,\1,\2,:;
tl;
#transform format back
s:,$::mg;s:^([^,]+),:\1\t:mg

답변2

파일이 아래와 같은 실제 csv 파일(simple-csv)인 경우 다음 awk명령을 사용할 수 있습니다.

입력하다:

[email protected]
[email protected]
[email protected],[email protected],[email protected]

주문하다:

awk -F, '{ COMMA="";i=0; while (++i<=NF) {
           $1=$i; printf (!seen[$1]++)?COMMA$i:""; COMMA=","}; print ""
}' infile.csv

산출:

[email protected]
[email protected]
[email protected],[email protected]

그렇지 않고 입력이 질문에 제공된 것과 같을 경우 다음을 사용할 수 있습니다.

awk  'NR==1; NR>1{id=$1"\t"; COMMA=$1="";split($0, ar, /,| /); 
    for(i in ar){if(ar[i]!=""){printf(!seen[ar[i]]++)?id""COMMA""ar[i]:""; COMMA=",";id=""}
} print ""}' infile

산출:

id  emails
1       [email protected]
2       [email protected]
3       [email protected],[email protected]

관련 정보