다음과 같은 (수천 또는 수백만) 개의 값 목록이 있습니다.
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 구성입니다 . 그런 다음 반복하여 발생 횟수를 합산하고 종료 조건이 일치할 때까지 고주파수 쌍을 인쇄합니다.awk
count
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