加入发出警告"文件1不按排序顺序"

时间:2014-10-29 09:12:31

标签: bash unix

在新版本的bash 4.1.2(1)中测试遗留脚本 - 发布 ,并在控制台中遇到此警告:

join: file 1 is not in sorted order
join: file 2 is not in sorted order

我很确定这两个文件都已排序。这些文件实际上合并得很合适。

以下是剧本:

cat $FILE1_PATH'.processed.1' | cut -d'|' -f4,8 | sort | uniq -u  > $FILE1_PATH.'processed.2'
cat $FILE2_PATH'.processed.1' | cut -d'|' -f1,8 | sort | uniq -u > $FILE2_PATH.'processed.2'
join -t$'|' -1 1 -2 1 $FILE1_PATH.'processed.2' $FILE2_PATH.'processed.2' > $MERGEFILE_PATH

执行此脚本:

  1. 从文件1中提取字段4和8
  2. 从文件2中提取字段1和8
  3. 使用连接键file1.field4 = file2.field1
  4. 组合提取的字段
  5. 删除所有重复项。
  6. FILE1.processed.2:

    21VIANET GP INC|GOV
    ABN|ABN1
    ABN|ABN2
    ABOC|ABOC1
    ABOC|ABOC1
    ABOC|ABOC2
    ....
    

    FILE2.processed.2:

    ABN|Banks
    ABOC|Pharmaceuticals
    GOV|Government Agency 
    ....
    

    输出:

    GOV|21VIANET GP INC|Government Agency
    ABN|ABN1|Banks
    ABN|ABN2|Banks
    ABOC|ABOC1|Pharmaceuticals
    ABOC|ABOC2|Pharmaceuticals  
    ....
    

    在bash版本3.2.25(1)中运行相同的脚本 - release不会发出警告。有什么想法解决警告吗?

    更新: 似乎原因是由输入文件中的这些行引起的......

    ADBC|Banks 
    ADB|Banks
    

    加入期望ADBC定位于亚行之后,如下所示:

    ADB|Banks
    ADBC|Banks
    

    但是我尝试将排序脚本从排序-u更改为排序-t $' |' -k1(基于第一个字段排序)但是仍然不起作用......

1 个答案:

答案 0 :(得分:2)

join手册页中的建议是在您加入字段1时使用sort -k 1b,1。(它表示“当连接没有选项时”,但就字段选择而言,您的加入相当于没有选项。-1 1-2 1是默认设置。)您可以向其添加-t '|',它将与join完美匹配。

-k1表示从1到结尾的所有字段。 -k1,1仅表示字段1.如果您有前导空格并想要忽略它,则b是必需的。排序语法很奇怪。这是之后 POSIX重新设计它以试图让它变得合情合理。如果你曾经写过一个看起来并不复杂的排序命令,它可能就没有你想要的那样。

--debug添加到sort命令中,以查看它作为键使用的内容。使用包含以下行的示例文件:

ADBC|Banks
ADB|Banks
 ADBC|Banks

您可以看到各种-k选项的效果:

$ sort -s -t '|' -k 1 --debug file
sort: using simple byte comparison
 ADBC|Banks
___________
ADBC|Banks
__________
ADB|Banks
_________
$ sort -s -t '|' -k 1,1 --debug file
sort: using simple byte comparison
 ADBC|Banks
_____
ADB|Banks
___
ADBC|Banks
____
$ sort -s -t '|' -k 1b,1 --debug file
sort: using simple byte comparison
ADB|Banks
___
ADBC|Banks
____
 ADBC|Banks
 ____

现在你可能想知道我扔在那里的-s。没有它,整个行的默认最后的比较作为字符串,适用于具有相同键的行。这通常不是问题,您可能不需要使用-s。只是当使用--debug时,最后的比较会使列表变得混乱,所以我喜欢使用-s来摆脱它。