「sort」コマンドを使用して、CSVファイルを列の優先度でソートします


91

私はcsvファイルを持っていますが、 "order by"のように列の優先度で並べ替えたいのですが。例えば:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

この状況が「select」の結果である場合、「order by」は次のようになります。orderby column2、column1、column3-結果は次のようになります。

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

Unixで「sort」コマンドを使用して同じ結果を得る方法を知りたいのですが。


4
ちなみに、これはssvファイルです(セミコロンで区切られた値):P
John Strood

回答:


153
sort --field-separator=';' --key=2,1,3

8
値が数値の場合は、-n「文字列の数値-gに従って比較する」オプションまたは「一般的な数値に従って比較する」オプションの使用を検討してください。数値の文字列比較では、のような順序で番号が取得されます1,10,2,20。少なくとも、これらはCentOSの私のバージョンのソートで使用できるオプションです。ソートのバージョンで正しいオプションが何であるかは、manページで確認する必要があります。
Adam Porad 2013年

4
私が得るsort: stray character in field spec: invalid field specification ‘2,1,3’
マーティン・トーマ2014

3
しかし、sort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csv私のために働いた。
Martin Thoma 14

6
@MartinThoma久しぶりですが、私はあなたの問題に遭遇し、それを見つけましたsort --field-separator=';' --key={2,1,3}。これはGNU coreutils 8.42016
mrbolichi 2018年

2
@mrbolichi表記--key={2,1,3}はbashのブレース展開を使用します
kvantour

28

ファイルに別の行3;10;3があるとしunsorted.csvます。次に、数値でソートされた結果を期待していると思います。

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

アルファベット順にソートされたものではありません:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

それを取得するには、以下を使用する必要があります-n

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

2,2使用する必要があることに言及する価値があります。のみ2を使用する場合sort、フィールド2の最初から最後まで文字列を取ります。2,2フィールドのみ2が使用されていることを確認します。


7
-k 2と-k 2,2の違いに関するポインタは重要です。manページを初めて読んだとき、これを見落としていた。ありがとう。
usonianhorizo​​n

私は、いくつかの余分な行を追加して3;10;33:10:53:10;23;10;3ソースファイル内の順で、かつ使用しているときだけ -k 2,2、manページが言うコラム2及び3にソートするために表示されます"The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal."。私の場合、以前のキー(値= 10)は同等に比較しましたが、-k複数回指定しませんでした。これが信頼できる動作なのか、それとも私のシステム(mac)に関連するのかはわかりません。最終的には、一次ソートが正しい限り、それは問題ではありません。
ダボス

ああ-s、同等のキーを無視する安定したソートもあると思います。
ダボス

24

上記のチャーリーの答えは、Cygwin(ソートバージョン2.0、GNU textutils)では機能しませんでした。

sort -t"," -k2 -k1 -k1

3
Cygwinには古いバージョンのソートがあります。いつものように、manページはあなたの友達です。
チャーリーマーティン

2
@CharlieMartinに同意します。システムのmanページを確認してください。CentOSで私が使用したsort --field-separator=';' -k2 -k1 -k3 test.csv
Adam Porad

-6

..そして、誰かが「ソート」ソリューションに従っていたが、現在、1行あたりの単一の一意のエントリ(つまり、上位X個の一意のエントリ)より多くを取得したい場合、「ソート」を使用してファイルをソートすると、次のように使用できます。ここで作成した小さなアプリ:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java


2
よかったね!しかし、あなたの場合、あなたは単に使用することができますcat unsorted-file | sort | uniq | head -X- Xはあなたが出力したい最初の行の数です。
Slavik Meltser、2016年

@SlavikMeコメントありがとうございます!ただし、提案の結果は異なります。提案では、完全にソートされたファイルの最初のX行を取得しますが、「キー」ごとに最初のX行を取得します(つまり、名前付きのCSVがある場合、ソートすると列2の「ラストネーム」では、コマンドはおそらく「アレン」を姓として3行しか取得しませんが、「アレン」、「イギリス」、「チャールズ」などを取得します。ありがとうございます!
Daniel Iversen

6
あなたは間違っている。コメントを書く前に、書いたコマンドを試してみることをお勧めします。とのuniq間にパイプ順のコマンドがあることに注意してください。これにより、最上位の行を抽出する直前に、並べ替えられたすべての行に一意性が与えられます。sorthead
Slavik Meltser 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.