2011-12-06 19 views
4

私はユニコードsortコマンドを使用して "直感的な" /自然な方法でアルファベットの文字と数字の文字列をソートしようとしていますが、正しくソートすることはできません。私は、このファイルを持っている:直感的@42EBKAAXX090828:6:10:...は(10100102よりも小さいので)、第二@42EBKAAXX090828:6:100...であり、第3は@42EBKAAXX090828:6:102:204:1871/2である第一であるソートでUnixで英数字をソートする方法は?より複雑なようです

$ cat ~/headers 
@42EBKAAXX090828:6:100:1699:328/2 
@42EBKAAXX090828:6:10:1077:1883/2 
@42EBKAAXX090828:6:102:785:808/2 

私は英数字でソートしたいのですが、。

ここでは、ライン内の特定の位置をソートすることをお勧めしますが、ここでは:の位置が変わる可能性があるため、ここでは一般的で実行可能な解決策ではありません。

私が試した:-n-uパラメータの様々な組み合わせで

sort --stable -k1,1 ~/headers > foo 

を、それは正しい順序を与えるものではありません。

どのようにすれば、効率的に行うことができますか?sortを使用しているbashまたはPythonからですか?私はこれを4〜5 GBの丸いファイルに適用したいので、何百万もの行が含まれています。

ありがとうございます!

+1

これは通常、「Natural Sorting」と呼ばれます。 – yak

+0

パフォーマンスについてはわかりませんが、ここではPythonで自然なソートを実装しています:http://stackoverflow.com/q/4836710/331473 –

+0

'@ 42EBKAAXX09082 * 7 *:6:100:1699:328/2 'と' @ 42EBKAAXX09082 * 8 *:6:100:1699:328/2'(強調のための '*')?彼らは同じように並べ替えられていますか? (つまり、3番目のフィールドのみが関連します)、@ JonathanMの答えが最も良いです。そうでなければ鉱山を見てください – tobyodavies

答えて

11

-Vオプションは、あなたがやりたいように見えます - 自然なソートを。これは通常、自然のソートと呼ばれる

@42EBKAAXX090828:6:10:1077:1883/2 
@42EBKAAXX090828:6:100:1699:328/2 
@42EBKAAXX090828:6:102:785:808/2 
+0

whichc of UNDOCUMENTED ~~~~~ – user528025

+1

@ user528025いいえ、文書化されています。マニュアルページで "natural sort"を検索するとこのオプションが見つかりました。 – tobyodavies

4

のようにアルファベット順にソートします。 10:100102後に来ている理由は、コロン:ASCII chart9文字の後にあるので、10:は、それらの後であるということです。あなたはコロンで区切られた3番目のフィールドでソートしたいしている場合

、これを試してみてください。

sort -t':' -k3 ~/headers > foo 
+0

OPだけでそのフィールドをソートしたいのであれば幸いです。 – tobyodavies

+0

'-k3n'や' -k3,4n'を使って '10'の前に' 9'を並べる方が良いでしょう。第2位ではなく、表示された行を並べ替えるためにOPが '@ 43ZQRY101112:6:19:221:134/3'を望むと思う余地があるので、ソートはおそらく第3よりも多くのキーにある必要があります。データ '@ 6NBGD010101:9:99:999:111/3'または '@ 213QED081231:16:91:23:2/0'が表示されるかどうかを知ることは興味深いでしょう。 '@ 42E'を開始します。この問題は、入力データのばらつきを完全に把握していないため、まだ不十分です。 –

+0

@JonathanLeffler、かなり可能です。良いコメント。ありがとう。 –

0

(したがって、文字を選択)

sort -V ~/headers 

出力が明らかにバージョン番号を対象としています。あなたの例のデータセットに適した方法があります。

import re 

def natural_sorted(iterable, reverse=False): 
    """Return a list sorted the way that humans expect.""" 
    def convert(text): 
     return int(text) if text.isdigit() else text 
    def natural(item): 
     return map(convert, re.split('([0-9]+)', item)) 
    return sorted(iterable, key=natural, reverse=reverse) 

私はこれを見つけたhereと少し改善しました。

+0

これはUnixソートに比べてスケールアップされますか?長いファイルを何百万行も処理できますか? – user248237dfsf

関連する問題