큰 파일에서 처음 몇 개의 열이 동일한 두 번째 행 삭제

큰 파일에서 처음 몇 개의 열이 동일한 두 번째 행 삭제

다음과 같은 파일이 있습니다.

A 1 abc
A 1 def
A 2 ttt
B 2 ppp
B 2 qqq

처음 두 키가 동일할 때 첫 번째 행을 유지하고 싶습니다. 이렇게 합니다.

A 1 abc
A 2 ttt
B 2 ppp

내가 하나 찾았어이전 질문이로써 문제가 해결되었습니다. 그러나 내 파일 크기는 1.2GB이고 처음 19개 열과 일치합니다. 그래서 이것을 실행하면:

  awk  '!array[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19]++' infile > outfile

알겠어요:

cmd. line:2: (FILENAME=infile FNR=287807) fatal: dupnode: r->stptr: can't allocate memory (Not enough memory)

분명히 중복된 파일이 어디에 있는지 모르기 때문에 처리할 파일을 분할할 수 없습니다. 이 문제를 해결하기 위해 메모리와 속도를 기꺼이 교환하겠습니다. (파일에는 약 160만 줄이 있습니다.)

답변1

파일이 정렬된 것 같습니다.

sort -m -u -k 1,2 < file

-m~을 위한병합파일을 정렬하려는 시도는 수행되지 않지만 대신 -u(예:고유한-k 1,2) 처음 2개 필드(처음 19개 필드)로 구성된 정렬 키를 지정하는 것과 결합하여 -k 1,19처음 2개 필드에서 중복 항목을 제거합니다.

파일이 정렬되지 않은 경우(적어도 이 두 필드에서) 삭제하면 됩니다 -m. 그러나 결과는 결국 정렬됩니다. 정렬은 비용이 많이 들지만 메모리 측면에서는 대용량 파일을 정렬하는 데 임시 파일이 사용되므로( sort사용 가능한 디스크 공간이 필요하거나 있음) 괜찮습니다 ./tmp$TMPDIR

답변2

동일한 열을 결합하여 인덱스를 형성하는 것이 유효합니까? 위의 예를 들어 보겠습니다. 우리는 할 수있다--

 awk '{ind=""; for(i=1; i<3; i++) {ind=ind" "$i }  if (!arr[ind]) arr[ind]=$3  } END{for (i in arr) print i, arr[i]}'

  A 1 abc
  A 2 ttt
  B 2 ppp

물론 필요한 인덱스를 결합하려면 위의 루프를 변경해야 합니다.

답변3

미래의 경우에는 이렇게 할 수 있습니다. 그리고 배열을 사용하여 대용량 파일 문제를 해결할 수 있습니다. 필드 값이 변경될 때마다 배열이 삭제됩니다.

BEGIN{
    xd=""; 
}
{
    id=$1;

    if (id != xd)
    {
        for (x in arr)
        {
            print x,arr[x];
        }

        delete arr; #Each time the field one changes its value
        xd=id;
    }
    ind="";
    for (i=1; i<3; i++)
    {
        ind=ind $i;
    }
    if (!arr[ind])
    {
        arr[ind]=$3;
    }

}

END {
        for (x in arr)
        {
            print x,arr[x];
        }
}

산출:

$ awk -f script.awk file.txt
A1 abc
A2 ttt
B2 ppp

답변4

이 시도:

awk '_a[$1" "$2]++==0'  < filename

관련 정보