UNIXソートを使用してカスタムソートを行う方法は?


11

私はunixソートを使用して、複数の列を持つコンマ区切りファイルをソートしています。これまでのところ、これはデータを数値順またはアルファベット順で並べ替えるのに最適です。

並べ替え前のファイルの例:

C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

ファイルを並べ替えます。 $ sort -t ',' -k 2,2 -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

ソートされた結果:

A,Bahamas,Bahamas,Nassau,f,2
A,Canada,QC,Montreal,f,2
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1

ここに問題があります:カスタムソートに基づいて列2を並べ替えます。つまり、最初に米国、次にカナダ、次にバハマが必要です。

望ましいソート:

A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

unix sortに適用できるカスタムの並べ替え順序を渡す方法はありますか?何かのようなもの: $ sort -t ',' -k 2,2:'United States, Canada, Bahamas' -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

ありがとう!


3
これらの3つの値については、逆のアルファベット順が必要です。一般的なケースでは、名前を並べ替え順序番号にマップし、並べ替え順序番号を使用して並べ替えを行う必要があります。または、スクリプト言語を使用します... joinコマンドの1つはコマンドですが、多くの並べ替えが行われる可能性があります。入力ファイルjoinは1つの順序で並べ替える必要があります。その後、sort再度使用してデータを入れます。別の順序(および並べ替え後の手順として並べ替え順序列が失われる)。
ジョナサンレフラー、

あなたの入力例tfは、最後の行の代わりにあるべきではありませんか?
Lev Levitsky

レフ:はい、良いキャッチ。私の悪い; 切り取りと貼り付けが多すぎます(実際のデータセットがはるかに大きく、誤った行を誤って取得しました)。

あなたのデータと一致するように答えを更新しました。
Lev

回答:


8

他の答えとコメントは一般的な質問に答えます。実装は次のようになります。

$ cat order
Bahamas,3
Canada,2
United States,1

$ cat data
C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

$ sort -t, -k2 data | join -t, -11 -22 order - | sort -t, -k2n -k4,5 -k6r -k7nr | cut -d, -f 3,1,4-7
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

すばらしい、ご協力ありがとうございます。これは完璧に機能しました!

@jeweliaもう一度改善されましたが、sedここでは実際には必要ありませんでした。
Lev Levitsky 2012年

1

sortではできません。この時点で、実際にはawk / perl / your-language-of-choiceに到達しているはずです。ただし、それを変更することはできます。たとえば、sedを使用して「United States」を0に、「Canada」を1に、「Bahamas」を2に変更し、その列に対して数値ソートを実行してから、sedで戻すことができます。または、「United States」を「United States、0」などに変更し、追加の列に対して並べ替えてから破棄します。


0

私はちょうど書いたcsortと呼ばれるヘルパーをこれを実行することを容易にします。各行の先頭に、行内の部分文字列または正規表現の一致に基づいて選択した値を付けます。

$ csort -t, '2=United States' X 2=Canada Y 2=Bahamas Z < tmp.csv | \
sort -t, -k1,1 -k3,3 -k4,4 -k5,5 -k6,6r -k7,7nr
X,A,United States,MA,Boston,f,0
X,B,United States,NY,New York,f,5
X,A,United States,NY,New York,f,1
X,C,United States,WA,Tacoma,f,1
Y,A,Canada,QC,Montreal,f,2
Z,A,Bahamas,Bahamas,Nassau,f,2

2=STR表記手段「第2のフィールドが等しい場合に一致STR」。

次に、オプションで出力をパイプcut -c3-して、プレフィックスを削除できます。

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