Unixソートによる複数のキーのソート


137

1-nキーでソートする必要のある潜在的に大きなファイルがあります。これらのキーには、数値の場合とそうでない場合があります。これは固定幅のカラムナファイルなので、区切り文字はありません。

Unixソートでこれを行う良い方法はありますか?1つのキーで、「-n」を使用するのと同じくらい簡単です。manページを読んでGoogleを簡単に検索しましたが、良い例は見つかりませんでした。これを達成するにはどうすればよいですか?

注:ファイルサイズの可能性があるため、Perlを除外しました。それは最後の手段です。


1行または2行のサンプルデータは、コマンドラインの例を作成するのに非常に役立ちます。また、「1-n」キーは、可変数のキーでソートする必要があることを意味しますか?スクリプトなしでそれを行うのは楽しいでしょう...
Ken Gentle

1-n機能を有効にするために、sortコマンドの周りにPHPラッパーがあります。
Chris Kloberdanz 2008

回答:


69

-kオプション(または--key=POS1[,POS2])を使用します。複数回出現する可能性があり、各キーはグローバルオプション(n数値ソートなど)を持つことができます


7
sortのmanページから:「POSはF [.C] [OPTS]です。Fはフィールド番号、Cはフィールド内の文字位置です。どちらも原点1です。」完全なドキュメントについては、manページを参照してください。
Adam Rosenfield、

49
狂気になりたくない場合は、アンドラスの答えも参照してください。
ron

1
上記の両方のコメントは正確で付加的です。皆さん、ありがとう。
Ken Gentle

314

しかし注意してください:

ファイルを主にフィールド3でソートし、次にフィールド2でソートする場合は、次のようにします。

sort -k 3,3 -k 2,2 < inputfile

これでは sort -k 3 -k 2 < inputfileありません。これは、フィールド3の先頭から行の末尾(一意である可能性があります)までの文字列でファイルを並べ替えます。

-k, --key=POS1[,POS2]     start a key at POS1 (origin 1), end it at POS2
                          (default end of line)

8
生活変化。ありがとう。
davidtbernal 2014

2
おっと!私は、私はまだスクリプトの出力に依存していない上...良いこと最初の答え....見早いので、今、私は、スクリプトを修正する必要がある
ワイルドカード

いいね!ここで、フィールド2を数値で逆順にソートし、フィールド2を非数値で通常の(昇順)ソートにしたい場合はどうなりますか?:)
アルン2017

2
@Arun POSはmanページの最後で説明されています。あなたは、このようなフィールド番号に順序オプションを追加しますsort -k 3,3nr -k 2,2
アンドラーシュ

1
ああ。どのような直観に反するインターフェイスを:-k2あるべき-k2,2と末尾のコンマは-k2,「行または任意の魔法のデフォルトの終了」でなければなりません。
android.weasel 2017年

94

-kオプションが必要です。

-k 1.4,1.5n -k 1.14,1.15n

最初のフィールドで文字位置4〜5を使用し(固定幅ではすべて1つのフィールドです)、最初のキーとして数値で並べ替えます。

2番目のキーも、最初のフィールドの文字14〜15になります。

(編集)

例(DOS / cygwinが便利です):

dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r

データ用:

12/10/2008  01:10 PM         1,564,990 outfile.txt

ディレクトリリストを月番号(pos 4-5)で数値順に並べ替え、次にファイル名(pos 40-60)で逆順に並べ替えます。タブがないため、ソートするのはすべてフィールド1です。


入力データに空白がない場合は、1つのフィールドのみです。それにもかかわらず、あなたの例は役に立ちます。
Jonathan Leffler

修正:入力データに/ tabs /がない場合。DOSの「dir」コマンドの出力には、タブがありません。
クリントンピアス

オプション(数値、逆)の使用例は、manページからのみ使用する方法を見つけることはほぼ不可能であり、他の回答では言及されていないため、非常に役立ちます。これで+2ができたらなあ。;)
msb

22

これは、csvファイルのさまざまな列を数値および辞書順で並べ替えるためのもので、列5以降は辞書順として

~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d  sort.csv
1,10,b,22,Ga
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C

~/test>cat sort.csv
2,3,a,9,C
2,2,b,20,F
2,2,c,19,Gb,hj
2,2,c,19,Gb,hi
2,2,c,19,Ga
2,2,b,22,Ga
1,10,b,22,Ga

-k1,1nは、列1で始まり、列1で終わる数値を意味することに注意してください。以下を実行すると、列1と2を連結して、1,10を110としてソートします。

~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d  sort.csv
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C
1,10,b,22,Ga

1
それは別の列に異なるスイッチを使用する方法を示していますので、これが最良の答えです
xaxa

12

私はあなたの場合のようなものを信じています

sort -t@ -k1.1,1.4 -k1.5,1.7 ... <inputfile

よりよく機能します。@はフィールド区切り文字です。どこにも表示されない文字であることを確認してください。その場合、入力は1つの列で構成されると見なされます。

編集:明らかにclintpはすでに同様の答えを出しました、申し訳ありません。彼が指摘するように、フラグ「n」と「r」はすべての-k ....オプションに追加できます。


docsgnu.org/software/coreutils/manual/html_node/…によると、デフォルトの区切り文字はスペースですが、フィールド数が予想と異なる場合があります。おそらく他の人がLC_CTYPEロケール設定のためにここで言ったように。疑問がある場合は、行の最初から数えてください!
Brad Dre

5

-sランクの行が出力でも元の相対的な順序を維持するように、スイッチでソートを安定させることも望ましい場合があることに注意してください。


2

ヒントをいくつか追加したいのですが、sortを使用するときは、キー比較の順序に影響するロケールに注意してください。通常は、明示的にLC_ALL = Cを使用して、希望するロケールを作成します。


LC_ALL = Cを使用すると、速度もかなり向上します。
mat kelcey 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.