ソートがソート順を知らない場合のGNUソート安定ソート


18

2列のファイルがあります。ファイルは既に列1で希望どおりにソートされています。各列1カテゴリ内の列2で並べ替えたいと思います。ただし、sort列1のソート順を理解していません。

通常の方法(スタック上の同様の質問から)はこれです:

sort --stable -k1,1 -k2,2n

しかし、k1は任意なのでソートを指定できません。

入力例:

C 2
C 1
A 2
A 1
B 2 
B 1

および出力:

C 1
C 2
A 1
A 2
B 1 
B 2

回答:


20

awkを使用して、各ブロックの新しい並べ替えを開始できます。

% awk -v cmd="sort -k2,2" '$1 != prev {close(cmd); prev=$1} {print | cmd}' foo
C 1
C 2
A 1
A 2
B 1
B 2
  • $1 != prev {close(cmd); prev=$1} -保存された値が異なる場合、新しいブロックがあるため、以前に開始されたブロックを閉じます sort
  • {print | "sort -k2,2"}'出力をsortにパイプし、まだ実行されていない場合は開始します(awkは開始したコマンドを追跡できます)

2
awkは本当に素晴らしいです。私はこれが私が期待していたものよりもずっと好きで、それはawkの飾り付け、並べ替え、装飾解除でした!
エヴァンベン

私はこれと他の答えのパフォーマンスを比較しようとしましたが、なぜこれがより多くのリソースを使用するのか分かりません...アイデアはありますか?gist.github.com/EvanTheB/5b64eafb84eeaf51c289295ac06e1b0b
Evan Benn

平均して何回実行しましたか?
muru

平均化は行いませんでしたが、繰り返し調査すると、一貫したランタイムが表示されます。
エヴァンベン

ここでは、調査したい場合は、私が使用しているものと同様のファイルがある:seq 30 | xargs -L1 bash -cs 'yes $1 | head -1000000 | paste - <(seq 1000000) | shuf' bash
エヴァン・ベン

12

あなたは使うことができシュワルツ変換(これは基本的にあるよりも飾るソート-undecorateあなたはコメントで示唆したアプローチが、おそらくよりパフォーマンスmuruの 罰金の答えを伴う単一使用してsort使用して-複数のとは対照的に、呼び出し)awkという接頭辞列を追加します最初の列の値の変化に応じて増分し、接頭辞列の後に「2番目」の列(順序列の位置が3接頭辞列の存在により一時的に移動した)でソートされ、最後に接頭辞列を取り除きます

awk '{print ($1 in a? c+0: ++c)"\t" $0; a[$1]}' file | sort -k1,1n  -k3,3 | cut -f 2-

驚きましたが、あなたは正しいです、これは他の答えよりも速かったです!1億行のファイルで3分と2分(最初の列が30個まで)。
エヴァンベン

1
最初の列の一意のキーの配列を保持する必要はありません。現在の行の最初の列と前の列を比較するのに十分なはずだと思います。
クサラナンダ

awk -v OFS="\t" '$1 != prev { key++ } { print key, $0; prev = $1 }(未テスト)のようなもの。
クサラナンダ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.