我正在尝试对一些简单的管道分隔数据进行排序。然而, sort 实际上并不是排序。它将我的标题行移到底部,但我以 241 开头的两行被以 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
Run Code Online (Sandbox Code Playgroud)
列标题被移到文件的底部,所以 sort 显然正在处理它。但是,实际值并没有像我期望的那样排序。
在这种情况下,我解决了它
sort sort_fail.csv --field-separator='|' -k1,1
Run Code Online (Sandbox Code Playgroud)
但是,我觉得应该没有这个必要。为什么排序不是排序?
Ste*_*ris 32
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
Run Code Online (Sandbox Code Playgroud)
这可能会导致脚本出现问题,因为您可能不知道调用区域设置为什么,因此可能会得到不同的结果。
脚本强制所需的设置并不少见
例如
$ grep 'LC.*sort' /bin/precat
LC_COLLATE=C sort -u | prezip-bin -z "$cmd: $2"
Run Code Online (Sandbox Code Playgroud)
现在有趣的是,这里的|
角色看起来很奇怪。
但那是因为源自 ISO 的 en_US 的默认规则说
$ grep 007C /usr/share/i18n/locales/iso14651_t1_common
<U007C> IGNORE;IGNORE;IGNORE;<j> # 142 |
Run Code Online (Sandbox Code Playgroud)
这意味着该|
字符被忽略,排序顺序就好像该字符不存在一样..
$ tr -d '|' < sort_fail.csv | LANG=C sort
24121220810378
241212810172
24121320810376
column_acolumn_bcolumn_c
Run Code Online (Sandbox Code Playgroud)
这与您看到的“意外”排序相匹配。
变通方法是使用-n
(强制数字排序),或使用字段分隔符(如您所做的那样)或使用C
语言环境。
归档时间: |
|
查看次数: |
2279 次 |
最近记录: |