最高得点のアイテムを出力

最高得点のアイテムを出力

以下のファイルがあります。スコア列に基づいて、以下のように行全体を出力して、被験者ごとのスコアが最も高い人を出力したいと思います。特定の順序は必要ありませんが、件名列にはすべての一意の項目を含める必要があります。

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)。入力の3番目の列()で-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文字を次のように設定します。F生産するS入力区切り記号と酸素出力F生産するS出力区切り記号。
  • 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トピック別に(2番目のフィールド)並べ替え、スコア別に-k 3n n(3番目のフィールド)並べ替えます。この-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

入力ファイルを2回パスします。最高のスコアは最初のパスに書き込まれ、その行は2番目のパスに印刷されます。スコアがゼロより大きいと仮定します。

関連情報