csvファイルの最後の列(または数値がある他の列)に基づいてソート

csvファイルの最後の列(または数値がある他の列)に基づいてソート

次の内容を含むファイルがあります。行の残りの部分を維持しながら、最後の列(最後の列の3番目の列、他のファイルの場合)に基づいてファイルをソートしたいと思います。

ABC,DEF,GHI,-5,-8,-0.6,0.488 
XYZ,JKL,MNO,3,-5,0.2,-0.342 
STU,WXY,DEF,-1,4,0.01,0.345 

このコマンドを使用すると、期待どおりに機能し、正しい結果が表示されます。

awk '{print $NF,$0}' FILE | sort -nr | cut -f2- -d' '
XYZ,JKL,MNO,3,-5,0.2,-0.342 
STU,WXY,DEF,-1,4,0.01,0.345
ABC,DEF,GHI,-5,-8,-0.6,0.488 

ただし、大きなファイルで同じコマンドを実行すると、誤った結果が発生します。 (並べ替えるファイルには4M行があります。)次のように入力します。

ABC,DEF,GHI,-5,-8,-0.6,0.0488 
XYZ,JKL,MNO,3,-5,0.2,-0.0342 
STU,WXY,DEF,-1,4,0.01,0.0345 
JKL,JKL,GHI,-2,-3,0.31,-0.0524 
QRS,GHI,YUT,-3,-1,0.20,-0.0503 
HUR,JTL,ZST,1,1,0.52,-0.0556 
FTT,JL,MKI,0,2,0.21,-0.0529 
FTC,JKL,ERW,-1,6,0.23,-0.0441 
HJI,MHP,VGT,1,-6,0.80,-0.0433 
BUT,IOP,HGT,2,2,0.2,-0.0439 
XYZ,BGY,MNO,-2,1,0.01,-0.0416 

ベストアンサー1

どのくらいのフィールドがあるかを知っている場合:

$ sort -t, -k7,7n file
XYZ,JKL,MNO,3,-5,0.2,-0.342
STU,WXY,DEF,-1,4,0.01,0.345
ABC,DEF,GHI,-5,-8,-0.6,0.488

またはそうでない場合:

$ awk 'BEGIN{FS=OFS=","} {print $NF,$0}' file | sort -t, -k1,1n | cut -d, -f2-
XYZ,JKL,MNO,3,-5,0.2,-0.342
STU,WXY,DEF,-1,4,0.01,0.345
ABC,DEF,GHI,-5,-8,-0.6,0.488

最後のフィールドの代わりに最後から3番目のフィールドに基づいてソートすることは明らかです。

$ awk 'BEGIN{FS=OFS=","} {print $(NF-2),$0}' file | sort -t, -k1,1n | cut -d, -f2-
ABC,DEF,GHI,-5,-8,-0.6,0.488
XYZ,JKL,MNO,3,-5,0.2,-0.342
STU,WXY,DEF,-1,4,0.01,0.345

複数行に同じソートフィールド値がある場合に入力順序を維持するには、GNUソートを使用できます。それ以外の場合は、-s行番号を補助ソートキーとして含めます。

$ awk 'BEGIN{FS=OFS=","} {print $NF,NR,$0}' file | sort -t, -k1,1n -k2,2n | cut -d, -f3-
XYZ,JKL,MNO,3,-5,0.2,-0.342
STU,WXY,DEF,-1,4,0.01,0.345
ABC,DEF,GHI,-5,-8,-0.6,0.488

おすすめ記事