가장 높은 점수를 가진 항목을 출력

가장 높은 점수를 가진 항목을 출력

아래와 같은 파일이 있습니다. 점수 열을 기준으로 다음과 같이 전체 행을 출력하여 과목별 점수가 가장 높은 사람을 출력하고 싶습니다. 특정 순서는 필요하지 않지만 제목 열에는 모든 고유 항목이 포함되어야 합니다.

name subject score remarks
john   Math    67   satis
lewis  History 56   poor
sarah  Math    89   good
fiona  Geo     65   satis
george History 99   very good

원하는 출력:

name   subject score remarks
sarah  Math    89   good
george History 99   very good
fiona  Geo     65   satis

모든 열은 탭으로 구분되며 메모 열에만 공백으로 구분된 단어가 있습니다. 동일한 과목에 대해 동일한 점수가 존재한다면, 모두 출력하고 싶습니다.

답변1

그것은 다음과 같습니다:

{
head -n 1 file.txt &&
tail -n+2 file.txt |
sort -t $'\t' -nrk 3 |
awk -F '\t' 's[$2] && s[$2] > $3 { next }{ s[$2] = $3 } 1'
} >outfile.txt
  • head -n1제목을 인쇄하세요.

  • tail -n+2처리를 위해 헤더와 파이프라인의 나머지 부분을 건너뜁니다.

  • sort숫자를 역순으로 정렬합니다(높은 순서에서 낮은 순서로)( -rn). 입력의 세 번째 열( )을 기준으로 -k 3정렬 하고 탭으로 구분합니다( -t $'\t'이름이나 제목 열에 공백이 없는 경우 -를 제거할 수 있음).

  • awk제목이 보이지 않거나 마지막 줄과 같으면 해당 줄을 인쇄합니다.
    -F '\t'필드 구분 기호를 탭으로 설정합니다. 이름 및 제목 열에 공백이 없으면 제거할 수 있습니다.

    • s[$2] && s[$2] > $3 { next }다음; s[subject]이 설정되어 있고 현재 값(최고 점수)보다 큰 경우입니다.
    • {s[$2] = 1}놓다s[subject] = score
    • 1인쇄

마지막 줄의 제목이 마음에 들지 않고 생각할 필요도 없다면이름또는주제공백 포함(예: 없음) - 다음과 같이 단축할 수 있습니다.

sort -nrk3 file.txt | awk ' s[$2] && s[$2] > $3{next}{s[$2]=$3}1'

답변2

awk 'BEGIN{ FS=OFS="\t" }
    NR==1              { print; next }
    max[$2]<$3 || NR==2{ max[$2]=$3; data[$2]=$0; next }
    max[$2]==$3        { data[$2]= data[$2] ORS $0 }

END{ for(x in data) print data[x] }' infile

  • BEGIN{ FS=OFS="\t" }, 탭 \t문자를 다음으로 설정하십시오.에프생산하다에스입력 구분 기호 및산소산출에프생산하다에스출력 구분 기호입니다.
  • NR==1{ print; next }, 제목 행을 출력합니다.
  • max[$2]<$3 || NR==2{ max[$2]=$3; data[$2]=$0; next }, 각 과목에 대해 가장 높은 점수를 업데이트 및 유지하고 해당 높은 점수 과목에 대한 전체 행을 유지합니다.
  • max[$2]==$3{ data[$2]= data[$2] ORS $0 }, 각 동일한 과목에 대해 동일한 최고 점수를 가진 레코드를 추가합니다.
  • END{ for(x in data) print data[x] }, 데이터 배열을 반복하고 최종 결과를 인쇄합니다.

답변3

GNU를 사용하여 각 주제의 첫 번째 항목만 sort정렬하고 가져옵니다.uniq

sort -t '\t' -r -k 2 -k 3n scores.txt | uniq -f 1 -w 7

-k 2주제별로(두 번째 필드) 정렬 -k 3n n하고 점수별로(세 번째 필드) 정렬합니다. 이 -r옵션은 정렬 순서를 반대로 하여 점수가 가장 높은 항목이 먼저 표시됩니다.

이제 uniq두 주제를 모두 제거하고 첫 번째 필드를 건너뛰고 -f 15개만 비교하므로 HistoryA처음 5자를 공유하는 주제(예: and)에 대해서는 실패합니다 HistoryB.

uniqoptions 와 함께 명령을 사용하는 경우 -f첫 번째 필드에는 공백이 포함되어서는 안 됩니다. 그렇지 않으면 필드가 공백이 아닌 문자가 이어지는 일련의 공백(일반적으로 공백 및/또는 탭)이기 때문에 잘못된 출력이 생성됩니다. 필드 구분 기호를 지정 하는 옵션은 특정 버전의 Debian에서만 uniq사용할 수 있었지만 이제 호환성 이유로 제거되었습니다.-t

답변4

awk 'NR==FNR {if ($3>max[$2]) max[$2]=$3; next} FNR==1||$3==max[$2]' file file

입력 파일을 두 번 통과시킵니다. 가장 높은 점수는 첫 번째 패스에 기록되고 해당 행은 두 번째 패스에 인쇄됩니다. 점수가 0보다 크다고 가정합니다.

관련 정보