使用 Unix 命令“sort”排序不一致

使用 Unix 命令“sort”排序不一致

我正在运行以下命令:

zcat [File] | sed "1d" | sort -t $'\xE7' -k [field to be sorted] > [file].sorted

当我在文件 A 上运行此命令并按字段 1 排序时,我得到以下结果:

11622400 , abe, def
11622401 , abe, def
11622402 , bbabe, def
11622403 , ddabe, def
11622404 , acdc, dere
11622405 , ddabe, bere
11622406 , abe, fgh
11622407 , adbed, ddee
11622408 , adbe, def
11622409 , abdde, def
1162240 , abe, deed
11622410, def,dede

但是,当我对文件 2 运行相同的命令并按字段 2 排序时,我得到了以下结果:

1162303, 116224
1162420, 1162240
11623062, 11622400
11623063, 11622401
11623064, 11622402
11623065, 11622403
11623066, 11622404
11623067, 11622405
11623068, 11622406
11623069, 11622407
11623070, 11622408
11623071, 11622409
1162421, 1162241
11623072, 1162410

为什么排序方式不一样?第一个例子看起来不对,倒数第二行应该在最上面。

我正在尝试将这些文件与 Unix 合并加入命令,但由于这些命令的排序方式不同,因此遗漏了许多记录。

造成这个问题的原因是什么?

答案1

您得到这些结果的原因是您的排序不是数字的,而是基于列的规范值。

有一个命令行开关可以按数字排序,这就是您想要的(在您的谷歌栏中输入“man sort”)

答案2

你的问题有问题:你声称用作$'\xE7'记录分隔符,但文件中没有出现该字节。如果这确实是你运行的命令,并且这些确实是你的输出,那么文件 A 是基于整行排序的,而文件 B 是随机排序的(所有字段 2 都是空的,sort默认情况下不稳定)。但是,由于文件 2 看起来确实按,文件 B 输出中的第二个“ ”分隔字段排序,我猜这是你问题中的一个错误,要么你的代码使用空格或逗号作为分隔符,要么你的数据包含字节 E7,而这里的数据有一个逗号和一个空格。

如果您确实传递了-t选项来设置排序分隔符,则必须将相同的分隔符传递给join。无论如何,您需要告诉join要连接哪些列。例如:

<a.input sort -t $'\xE7' -k1 >a.sorted
<b.input sort -t $'\xE7' -k2 >b.sorted
join -1 1 -2 2 -t $'\xE7' a.sorted b.sorted >joined

此外,鉴于文件 A 的输出中“ 11622409 ,”出现在 ” 1162240 ,”​ 之前,看来您正在运行的sort区域设置会产生接近人类排序规则的结果(只是接近,因为sort不够精细,无法匹配严肃排版中使用的相当复杂的规则)。 如果您将区域设置更改为产生适合计算机使用的结果的区域,您将获得不那么令人惊讶的结果。 实际上,这意味着您的LC_COLLATE设置应该是C(或其同义词POSIX)。 (任何其他区域设置都倾向于破坏使用 的脚本sort,但您的脚本实际上应该没问题。)示例:

$ cat a
11622409 , abdde, def
1162241 , abe, deed
11622410, def,dede
$ LC_COLLATE=en_US sort <a
11622409 , abdde, def
11622410, def,dede
1162241 , abe, deed
$ LC_COLLATE=C sort <a
11622409 , abdde, def
1162241 , abe, deed
11622410, def,dede

join如果你在与 相同的区域设置中运行sort,那么应该没问题。请注意,sort会产生词汇上排序输出,而不是数值上已排序;但这就是您想要的输入join

答案3

尝试:

zcat [File] | sed "1d" | sort -tn $'\xE7' -k [field to be sorted] > [file].sorted

相关内容