以下のファイルがあります。スコア列に基づいて、以下のように行全体を出力して、被験者ごとのスコアが最も高い人を出力したいと思います。特定の順序は必要ありませんが、件名列にはすべての一意の項目を含める必要があります。
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 1
5つを比較するだけで、最初HistoryA
の5文字を共有するトピック(たとえば、and)は失敗しますHistoryB
。
uniq
options でコマンドを使用する場合、-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番目のパスに印刷されます。スコアがゼロより大きいと仮定します。