Linux join实用程序抱怨输入文件未被排序

时间:2014-08-21 16:48:23

标签: linux bash sorting join text-processing

我有两个文件:

file1的格式为:

field1;field2;field3;field4

(file1最初未分类)

file2的格式为:

field1

(file2已排序)

我运行以下两个命令:

sort -t\; -k1 file1 -o file1 # to sort file 1
join -t\; -1 1 -2 1 -o 1.1 1.2 1.3 1.4 file1 file2

我收到以下消息:

join: file1:27497: is not sorted: line_which_was_identified_as_out_of_order

为什么会这样?

(我还尝试对file1进行排序,考虑到整条生产线,不仅是生产线的第一批,还没有成功)

sort -t\; -c file1没有输出任何内容。在第27497行附近,情况确实很奇怪,这意味着排序无法正常工作:

              XYZ113017;...
line 27497--> XYZ11301;...
              XYZ11301;...

3 个答案:

答案 0 :(得分:9)

sort -k1使用从字段1开始的所有字段作为键。您需要指定一个停止字段。

sort -t\; -k1,1

答案 1 :(得分:9)

以更广阔的视角补充Wumpus Q. Wumbley's helpful answer(因为我发现这篇文章研究的问题略有不同)。

  • 使用join 时,输入文件必须仅通过加入字段排序 ,否则您可能会看到警告OP报道。

在排序输入文件时,有两个常见场景 more 比感兴趣的字段错误地包含:

  • 如果您指定了某个字段,那么很容易忘记您还必须指定停止字段 - 即使您只定位 1 < / em> field - 因为如果只指定了 start 字段,sort会使用该行的其余部分; e.g:

    • sort -t, -k1 ... # !! FROM field 1 THROUGH THE REST OF THE LINE
    • sort -t, -k1,1 ... # Field 1 only
  • 如果您的排序字段是输入中的第一个字段,则很难指定任何字段选择器

    • 但是,如果字段值可以是彼此的前缀子字符串,则排序整行不会(必然)产生与仅按第1字段排序相同的排序顺序
    • sort ... # NOT always the same as 'sort -k1,1'! see below for example

陷阱示例:

#!/usr/bin/env bash

# Input data: fields separated by '^'.
# Note that, when properly sorting by field 1, the order should
# be "nameA" before "nameAA" (followed by "nameZ").
# Note how "nameA" is a substring of "nameAA".
read -r -d '' input <<EOF
nameA^other1
nameAA^other2
nameZ^other3
EOF

# NOTE: "WRONG" below refers to deviation from the expected outcome
#       of sorting by field 1 only, based on mistaken assumptions.
#       The commands do work correctly in a technical sense.

echo '--- just sort'
sort <<<"$input" | head -1 # WRONG: 'nameAA' comes first

echo '--- sort FROM field 1'
sort -t^ -k1 <<<"$input" | head -1 # WRONG: 'nameAA' comes first

echo '--- sort with field 1 ONLY'
sort -t^ -k1,1 <<<"$input" | head -1 # ok, 'nameA' comes first

说明:

  • 当不限制排序到第一个字段时,它是字符的相对排序顺序。 {1}}和^(列索引6)在此示例中很重要。换句话说:将字段分隔符与数据进行比较,这是问题的根源:A的ASCII值高于^,因此对进行排序在&#39; A&#39;之后,导致以A排序的行在nameAA^之前排序。

  • 注意:可能会在一个平台上出现问题,但会根据区域设置和另一个 进行屏蔽字符集设置和/或使用的nameA^实现;例如,有效sort的区域设置,en_US.UTF-8作为分隔符,,允许内部字段:

      OSX 10.10.2( GNU -版本,5.93)上使用的
    • sortsort之前对,进行排序(符合ASCII值)
    • 在Ubuntu 14.04(GNU - 8.21)上使用的
    • sort执行相反:在sort [1]之前对-进行排序]

[1]我不知道为什么 - 如果有人知道,请告诉我。使用,

进行测试

答案 2 :(得分:-3)

...或gnu排序与其他所有GNU命令一样有漏洞

尝试对Gi1 / 0/11和Gi1 / 0/1进行排序,您将永远无法获得适合于联接输入的实际常规文本排序,因为有人在排序中添加了一些额外的智能,可以很高兴地使用数字或人类在这种情况下,可以自动进行数字排序,而不必费心添加一个标志来强制正常行为

最适合人类的东西很少适合脚本