파일에서 중복 레코드를 제거하고 고유 식별자를 무시합니다.

파일에서 중복 레코드를 제거하고 고유 식별자를 무시합니다.

28개 필드/헤더/속성(쉼표로 구분)이 포함된 파일이 있습니다. 필드 #은 레코드를 고유하게 만듭니다. 그러나 나머지 필드는 동일할 수 있습니다. 중복된 항목을 찾아 하나만 보관해야 합니다. 두 번째 반복보다 첫 번째 반복을 유지하는 것이 더 쉽다면 괜찮습니다. 예:

입력 파일:

1,ed23,jon,doe,director,usa
2,ed23,jon,doe,director,usa
3,er67,jake,Kogan,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

원하는 출력:

2,ed23,jon,doe,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

답변1

예제 입력은 혼란스럽습니다. 첫 번째 행(열 머리글)에는 필드 구분 기호 쉼표도 없고 대부분의 행에는 성과 성적 필드 사이에 쉼표가 없습니다.

약간 건전한 입력을 제공하기 위해 다음과 같이 편집했습니다.

$ cat input.txt 
ID, uid  ,firstname ,lastname,   grade    , country n28
1 , ed23 , jon     ,   doe   ,  director  ,  usa
2 , ed23 ,  jon     ,  doe   ,  director     , usa
3 , er67 ,  jake     , Kogan ,  director     , usa
4 , er67 ,  jake     , Kogan ,  director     , usa
5 , dc10 ,  Charls     ,Morg ,  manager      , usa
6 , kc56 ,  patel     ,Kumar ,  associate    , india

치트를 제거하는 간단한 구현은 다음과 같습니다.

$ awk -F' *, *' -v OFS=, \
    'NR==1 {$1=$1;$0=$0; print; next};
     {id=$1; $1=""; $0=$0; if (!seen[$0]++) {print id $0}}' input.txt 
ID,uid,firstname,lastname,grade,country n28
1,ed23,jon,doe,director,usa
3,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

이는 입력 필드 구분 기호( FS)를 0개 이상의 공백으로 설정하고 그 뒤에 쉼표, 0개 이상의 공백을 설정하고 OFS출력 필드 구분 기호( )를 쉼표로만 설정합니다. 즉, 모든 필드에서 선행 및 후행 공백을 효과적으로 제거합니다.

첫 번째 입력 라인( NR==1)의 경우 awk 트릭을 사용하여 입력 라인의 형식을 다시 지정합니다. 즉, 필드를 변경하고(심지어 원래 값으로 설정) 을 설정합니다 $0=$0. 라인은 새로운 OFS를 사용하도록 재형식화됩니다. 그런 다음 인쇄하고 다음 줄로 이동합니다.

나머지 입력의 경우 $1이라는 변수에 $1을 id빈 문자열로 설정한 다음 $0=$0ID와 줄의 나머지 부분을 인쇄하기 전에 트릭을 다시 사용합니다(줄에서 $1을 효과적으로 제거).

예제 출력과 달리 다음은 인쇄됩니다.첫 번째마지막 줄이 아닌 중복된 줄 - 처음 본 때는 감지하기 쉽지만 마지막으로 본 때는 감지하기 어렵습니다(입력 내용을 모두 읽지 않으면 알 수 없음). 또한 이는 반복 횟수를 계산하지 않습니다.

이 두 가지를 모두 수행하려면 출력을 생성하기 전에 전체 입력 파일을 읽고 두 번째 배열 ids( 중요한 라인일 수도 있습니다.

$ awk -F' *, *' -v OFS=, \
   'NR==1 {$1=$1;$0=$0",count";print;next};
   {id=$1; $1=""; $0=$0; seen[$0]++; ids[$0]=id};
   END { for (id in ids) {print ids[id] id, seen[id]} }' input.txt  | \
 sort -n
ID,uid,firstname,lastname,grade,country n28,count
2,ed23,jon,doe,director,usa,2
4,er67,jake,Kogan,director,usa,2
5,dc10,Charls,Morg,manager,usa,1
6,kc56,patel,Kumar,associate,india,1

sort -n이는 awk의 연관 배열이 순서가 없으므로 반 무작위 순서로 나타나기 때문에 사용됩니다. GNU awk에는 여기서 배열에 사용할 asort()수 있는 값으로 배열을 정렬할 수 있는 함수가 있지만 idsa) 이식성이 없고 b) 출력을 sort -n.

답변2

쉼표로 구분된 깔끔한 입력의 경우 awk다음과 같은 스크립트가 적합할 수 있습니다.

awk -F, '{X=""; for (i=2;i<29;i++) X=X " " $i;} \
     seen[X]!=1 {print;} \
     {seen[X]=1;}' < input

첫 번째 awk규칙은 입력에서 2~28개의 "단어"를 선택하여 "키"를 만듭니다(인수에 따라 -F,쉼표로 구분된 모든 항목은 "단어"임). 다음 규칙은 "키"가 이미 등록되지 않은 한 해당 줄을 인쇄하고 세 번째 규칙은 해당 줄에 대한 키를 등록합니다.

답변3

파일이 "간단한 CSV" 형식이라고 가정합니다. 즉, 데이터에 쉼표나 줄 바꿈이 포함되어 있지 않다는 의미입니다.

$ tac file | awk -F , '{ key = $0; sub("[^,]*,", "", key) } !seen[key]++' | tac
2,ed23,jon,doe,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

awk위 파이프라인 중간에 있는 코드는 첫 번째 행을 제외한 모든 필드에 대한 해시의 키로 사용될 문자열을 생성합니다. 그것은 인쇄됩니다첫 번째특정 키가 있는 행이 나타나고 모든 중복 항목은 무시됩니다.

당신이 얻고 싶어하는 것 같으니마지막tac반복하려면 (GNU coreutils에서)을 사용하여 프로그램에 입력하기 전에 입력 줄의 순서를 반대로 바꿉니다 awk. 그런 다음 프로그램의 출력을 반전시킵니다 awk.

이 접근 방식의 단점은 계산된 키가 모든 고유 행에서 첫 번째 필드를 뺀 크기를 합친 만큼의 메모리를 사용한다는 것입니다.

다음은 보다 메모리 효율적인 접근 방식이지만 중복 행이 항상 함께 표시되도록 입력이 정렬되어 있다고 가정합니다.

$ tac file | awk -F , '{ key = $0; sub("[^,]*,", "", key) } key != prev; { prev = key }' | tac
2,ed23,jon,doe,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

답변4

uniq위의 설명을 자세히 설명하려면 - 방법:

$ tr ',' '\t' < temp/testfile | uniq -f 1 | tr '\t' ','
1,ed23,jon,doe,director,usa
3,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

\t데이터에서 공백을 피하기 위한 구분 기호 로 사용됩니다 .

uniq발견된 첫 번째 고유 행이 유지됩니다. "마지막" 항목을 반드시 유지해야 하는 경우 파일 끝부터 처음까지 작업해야 합니다. 다음 방법을 사용하여 이 작업을 수행할 수 있습니다 tac.

$ tac temp/testfile|tr ',' '\t' | uniq -f 1 | tr '\t' ','|tac
2,ed23,jon,doe,director,usa
4,er67,jake,Kogan,director,usa
5,dc10,Charls,Morg,manager,usa
6,kc56,patel,Kumar,associate,india

관련 정보