다음보다 큰 중복 행 제거

다음보다 큰 중복 행 제거

따라서 다음 형식의 입력 파일이 있습니다.

Hello\tWorld

그럼 내가 사용할 수 있습니다

awk -F"\t" '!seen[tolower($1)]++'

첫 번째 열을 기준으로 중복 행을 제거합니다. 그런데 해당 문에서 조건을 어떻게 설정합니까? 즉, 문자열이 5번 이상 사용되면 중복된 행만 제거합니까, 아니면 모든 행을 제거합니까?

입력 예:

Hello   World
Hello   World
Hello   World
Hello   World
Hello   World
New Example
Hello   World

따라서 위의 예에서 column1은 5번 이상 존재하므로 예상되는 출력은 다음과 같습니다.

Hello   World
New     Example

또는 특정 행을 완전히 제거하려면

New Example

답변1

표현식은 배열 항목이 처음으로 존재하는지 여부를 테스트하는 부울 값입니다. 효과가있다! 조건을 뒤집으려면. 하지만계속 계산되고 있어.

그냥 테스트에 익숙해지세요. 버전 6 이상 인쇄를 거부합니다.

awk -F"\t" '++seen[tolower($1)] <= 5'

답변2

두 예제 모두 입력 파일을 두 번 읽습니다. 첫 번째 단계에서는 첫 번째 열의 개수를 계산하고, 두 번째 단계에서는 현재 행을 인쇄하여 개수와 비교합니다.

  1. 첫 번째 열이 5번 이상 나타나는 경우 첫 번째 발생 위치를 인쇄합니다.

    awk -F'\t' '
      FNR==NR{ seen[tolower($1)]++; next }
      seen[tolower($1)]
      seen[tolower($1)]>5{ delete seen[tolower($1)] }
    ' file file
    

    현재 행은 첫 번째 열이 배열( )에 있는 경우에만 인쇄됩니다 seen[tolower($1)]. 5번 이상 나타나면 배열에서 제거됩니다.

  2. 첫 번째 열이 5번 이상 나타나면 해당 행을 삭제합니다.

    awk -F'\t' '
      FNR==NR{ seen[tolower($1)]++; next }
      seen[tolower($1)]<=5
    ' file file
    

    열 수가 5개 이하인 경우에만 현재 행을 인쇄합니다.

답변3

전체 파일을 배열에 저장하면 파일을 두 번 읽지 않고도 모든 작업을 수행할 수 있습니다. 즉, 파이프라인에서 작동합니다. 파일을 두 번 읽는 것보다 복잡도가 더 높은지 비교하지는 않았지만 초당 약 275,000줄을 처리하고 있습니다. 나는 정기적으로 최대 400MB의 awk 배열을 사용하므로 데이터 크기는 문제가 되지 않습니다.

입력 파일의 크기와 키 개수를 보여줍니다.

Paul---) wc  53.txt
 100008  187520 1100108 53.txt
Paul---) cut -f1 53.txt | sort | uniq -c
  12500 Can
  12500 Care
  12500 If
  12500 Major
  12500 Minor
  12500 Not
      5 Oak
  12500 Sample
      1 Spruce
      2 Willow
  12500 With

이는 실행 및 타이밍을 보여줍니다. 입력 데이터의 전파, 나머지 라인과의 키 분리, 원래 시퀀스의 보존을 확인하기 위해 일부 디버깅도 필요합니다. Cat은 파이프 입력을 강제하는 데 사용됩니다.

Paul---) time cat 53.txt | ./5fold
Ln   5590 Num 5 Key :Oak: Oak   Fifth
Ln   8654 Num 2 Key :Willow: Willow Pattern China
Ln  13427 Num 1 Key :Spruce: Spruce Only One
Ln  65309 Num 5 Key :Oak: Oak   Fourth
Ln  70988 Num 5 Key :Oak: Oak   Third
Ln  83982 Num 5 Key :Oak: Oak   Second
Ln  87439 Num 5 Key :Oak: Oak   First
Ln  99977 Num 2 Key :Willow: Willow Weep for Me

real    0m0.359s
user    0m0.324s
sys 0m0.048s

테스트한 코드입니다.

#! /bin/bash

AWK='''
BEGIN { FS = "\t"; nMax = 5; }
function List (Local, j) {
    for (j = 1; j in X; ++j) {
        if (N[K[j]] <= nMax)
            printf ("Ln %6d Num %d Key :%s: %s\n", j, N[K[j]], K[j], X[j]);
    }
}
{ ++N[$1]; K[NR] = $1; X[NR] = $0; }
END { List( ); }
'''
    awk -f <( echo "${AWK}" ) 

관련 정보