
単純なパイプで区切られたデータをソートしようとしています。しかし、ソートは実際にはソートではありません。ヘッダー行は一番下に移動しますが、241 で始まる 2 行が 24 で始まる行に分割されます。
cat sort_fail.csv
column_a|column_b|column_c
241|212|20810378
24|121|2810172
241|213|20810376
sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c
列ヘッダーはファイルの一番下に移動するため、ソートがそれを処理することは明らかです。しかし、実際の値が期待どおりに並べ替えられません。
この場合、問題を解決しました。
sort sort_fail.csv --field-separator='|' -k1,1
しかし、私はこれが必要だとは思わない。ソートがソートされないのはなぜですか?
答え1
sort
ロケールを認識するので、LC_COLLATE設定(LANGから継承されます)によって異なる結果が得られます。
$ LANG=C sort sort_fail.csv
241|212|20810378
241|213|20810376
24|121|2810172
column_a|column_b|column_c
$ LANG=en_US sort sort_fail.csv
241|212|20810378
24|121|2810172
241|213|20810376
column_a|column_b|column_c
呼び出すロケールが何であるかわからないため、結果が異なる可能性があるため、スクリプトに問題が発生する可能性があります。
スクリプトが必要な設定を適用することはまれではありません。
例えば
$ grep 'LC.*sort' /bin/precat
LC_COLLATE=C sort -u | prezip-bin -z "$cmd: $2"
もう興味深いのは、この|
キャラクターが奇妙に見えるということです。
ただし、これはen_US(ISOから派生した)の基本規則が次のようになるためです。
$ grep 007C /usr/share/i18n/locales/iso14651_t1_common
<U007C> IGNORE;IGNORE;IGNORE;<j> # 142 |
つまり、|
役割は無視されるそして、ソート順はまるでキャラクターが存在しないようです。
$ tr -d '|' < sort_fail.csv | LANG=C sort
24121220810378
241212810172
24121320810376
column_acolumn_bcolumn_c
これは表示された「予期しない」ソートと一致します。
回避策は、-n
数値の並べ替えを強制的に使用するか、以前と同じようにフィールド区切り文字を使用するか、ロケール設定を使用することですC
。
答え2
残念なことは、24
それらの間の位置では動かないことです241
。 2番目のフィールドはで始まります1
。4
2番目のフィールドで先行ソートしようとすると24
下に移動するため、特に明記しない限りsort
無視されるようです。|
頑張ってsort -n
...
答え3
-n, --numeric-sort 文字列数値を基準に比較
210
23
-n がないと、テキストの 210 が私の文字であるため、23 より先になります。