2줄 블록에 대한 고유 인스턴스 계산 [닫기]

2줄 블록에 대한 고유 인스턴스 계산 [닫기]

주어진 입력:

144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
144.252.36.69
afrloop=32235330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603
222.252.36.69
afrloop=31135330165603

어떻게 출력할 수 있나요?

144.252.36.69
afrloop=32235330165603 3 times
222.252.36.69
afrloop=31135330165603 4 times

답변1

paste - - < file | sort | uniq -c

답변2

awk사용자 정의 출력 형식을 원한다면 이것이 해결책입니다

NR%2==1 {ip=$0; next}
NR%2==0 {a[ip"\n"$0]++}
END {
    for(i in a)
        printf "%s %d times\n", i, a[i]
}

스크립트는 다음과 같이 실행될 수 있습니다.

awk -f main.awk file

설명하다

  • 먼저, 홀수 모듈로 2가 1과 같기 때문에 홀수 행을 일치시키는 데 사용합니다 NR%2==1. 행이 이 조건과 일치하면 전체 행을 $0이름이 지정된 변수에 저장합니다 ip. 이를 사용하여 next추가 처리를 건너뛰고 다음 반복으로 직접 이동할 수 있습니다.

  • 둘째, 짝수 행을 일치시키는 데 사용합니다 NR%2==0. 행이 일치하면 ip"\n"$0배열 에 인덱스를 만들고 a해당 특정 인덱스에 대한 개수 값을 증가시킵니다. 예를 들어, 동등한 확장은 다음과 같습니다

    a["144.252.36.69 afrloop=32235330165603"] += 1
    

    \n단순화를 위해 이 예에서는 새 줄을 무시합니다.

  • 마지막으로 END, 각 행을 처리한 후 루프를 사용하여 for배열 내의 각 요소 값 a(이 경우에는 각 고유 인덱스의 개수)을 인쇄합니다.

재미있는 벤치마크

  • 테스트 파일 생성(100만개 레코드)

    awk '
        BEGIN{for(i=1;i<10000000;i++)
        printf "%d\nafrLoop=%d\n", int(rand()*100), int(rand()*10)}
    ' > test
    
    $ head test
    23
    afrLoop=2
    84
    afrLoop=1
    58
    
  • @n.caillou 페이스트 솔루션

    $ time paste - - < test | sort | uniq -c > /dev/null
    real    0m11.250s
    user    0m11.352s
    sys     0m0.272s
    
  • 이상한 솔루션

    $ time awk -f main.awk test > /dev/null
    real    0m5.673s
    user    0m5.636s
    sys     0m0.036s
    

관련 정보