목록에서 가장 대표적인 값을 선택하세요.

목록에서 가장 대표적인 값을 선택하세요.

다음과 같은 (수천 또는 수백만) 개의 값 목록이 있습니다.

echo -e "y\ny\ny\nu\ni\no\no\nl\no\nj\nk\nl\nk\nl\nk\nl\nk\nl\nk\nl\no\nu\no\no\nu\ny\nl\ni\nq\nw\ne\nr\nt\na\ns" > list.txt

목록에서 각 값이 나타나는 횟수를 계산한 다음 keep목록에 있는 항목의 일부를 나타내는 가장 일반적인 값( )을 선택하고 싶습니다. 실제 데이터 세트에서 연결이 끊어지는 것에 대해서는 관심이 없습니다.

현재 작업 코드는 다음을 사용 sort | uniq | sort합니다 awk.

keep=0.50
sort list.txt | uniq -c | sort -nr > temp
awk -v keep=$keep 'NR==FNR {s+=$1}; NR!=FNR {c+=$1; print $0}; c > (s * keep) {exit 0}' temp temp
      7 l
      6 o
      5 k

그러나 두 코드 모두 매우 어색해 보입니다. 더 좋은 방법이 있나요? 올바른 검색어를 찾을 수 없습니다(따라서 이 질문의 제목이 잘못되었습니다).

답변1

단일 awk명령(GNU 버전)을 사용하여 포함된 값을 기준으로 배열을 고유하게 정렬할 수 있습니다. count파일의 각 줄의 발생 횟수를 고유하게 계산하는 연관 배열 입니다 .

이것은 값의 내림차순으로 배열의 항목을 정렬하는 PROCINFO["sorted_in"] = "@val_type_desc"GNU 구성입니다 . 그런 다음 반복하여 발생 횟수를 합산하고 종료 조건이 일치할 때까지 고주파수 쌍을 인쇄합니다.awkcount

awk -v keep=0.50 '
{
    count[$0]++
}

END {
    PROCINFO["sorted_in"] = "@val_type_desc"
    for (i in count) {
        sum += count[i]
        print i, count[i]
        if (sum > (NR * keep)) {
            break
        }
    }
}' list.txt

관련 정보