web-dev-qa-db-ja.com

Bash:テキストファイルを最後のフィールド値で並べ替えます

〜300k行を含むテキストファイルがあります。各行にはさまざまな数のコンマ区切りフィールドがあり、最後のフィールドは数値であることが保証されています。この最後の数値フィールドでファイルを並べ替えたいと思います。できません:

sort -t, -n -k 2 file.in > file.out

各行のフィールド数は一定ではないためです。 sed、awkが答えかもしれないと思いますが、方法はわかりません。例えば:

awk -F, '{print $NF}' file.in

最後の列の値を教えてくれますが、これを使用してファイルを並べ替える方法は?

23
Richard H

Awkを使用して、数字キーを前面に配置します。 $NFは、現在のレコードの最後のフィールドです。ソート。 sedを使用して、重複するキーを削除します。

awk -F, '{ print $NF, $0 }' yourfile | sort -n -k1 | sed 's/^[0-9][0-9]* //'
33
Fred Foo
vim file.in -c '%sort n /.*,\zs/' -c 'saveas file.out' -c 'q'
3
Benoit

私は代わりにここに私のものを投げ込むつもりです(そして私はawkを動作させることができませんでした):)

サンプルファイル:

Call of Doody                           1322
Seam the Ripper                         1329
Mafia Bots 1                            1109
Chicken Fingers                         1243
Batup Light                             1221
Hunter F Tomcat                         1140
Tober                                   0833

コード:

for i in `sed -e 's/.* \(\d\)*/\1/' file.txt | sort`; do grep $i file.txt; done > file_sort.txt
0
mmrtnt

Pythonワンライナー:

python -c "print ''.join(sorted(open('filename'), key=lambda l: int(l.split(',')[-1])))"
0

並べ替える前に、ファイルの各行のフィールドを逆にするのではないでしょうか。何かのようなもの

Perl -ne 'chomp; print(join(",",reverse(split(","))),"\n")' |
  sort -t, -n -k1 |
  Perl -ne 'chomp; print(join(",",reverse(split(","))),"\n")'

カンマが引用されない限り、それを行う必要があります。これが本格的なCSVファイル(コンマを円記号またはスペースで引用できる)の場合は、実際のCSVパーサーが必要です。

0
zwol

Perlワンライナー:

@lines=<STDIN>;foreach(sort{($a=~/.*,(\d+)/)[0]<=>($b=~/.*,(\d+)/)[0]}@lines){print;}
0
Benoit