在新版本的 bash 4.1.2(1)-release 中测试遗留脚本,并在控制台中遇到此警告:
join: file 1 is not in sorted order
join: file 2 is not in sorted order
Run Code Online (Sandbox Code Playgroud)
我很确定这两个文件都已排序。这些文件实际上已正确合并。
下面是脚本:
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
Run Code Online (Sandbox Code Playgroud)
这个脚本的工作:
FILE1.processed.2 :
21VIANET GP INC|GOV
ABN|ABN1
ABN|ABN2
ABOC|ABOC1
ABOC|ABOC1
ABOC|ABOC2
....
Run Code Online (Sandbox Code Playgroud)
FILE2.processed.2 :
ABN|Banks
ABOC|Pharmaceuticals
GOV|Government Agency
....
Run Code Online (Sandbox Code Playgroud)
输出:
GOV|21VIANET GP INC|Government Agency
ABN|ABN1|Banks
ABN|ABN2|Banks
ABOC|ABOC1|Pharmaceuticals
ABOC|ABOC2|Pharmaceuticals
....
Run Code Online (Sandbox Code Playgroud)
在 bash 版本 3.2.25(1)-release 中运行相同的脚本不会发出警告。任何想法来解决警告?
更新:似乎原因是由输入文件中的这些行引起的......
ADBC|Banks
ADB|Banks
Run Code Online (Sandbox Code Playgroud)
Join 期望 ADBC 位于 ADB 之后,如下所示:
ADB|Banks
ADBC|Banks
Run Code Online (Sandbox Code Playgroud)
但是我尝试将排序脚本从 sort -u 更改为 sort -t$'|' -k1(根据第一个字段排序)但是仍然无法正常工作...
小智 8
join手册页中的建议是sort -k 1b,1在您加入字段 1 时使用。(它说“当加入没有选项时”但就字段选择而言,您的加入相当于没有选项。-1 1并且-2 1是默认值。 ) 你可以添加-t '|'它,它会join完美匹配你的。
-k1表示从 1 到结尾的所有字段。-k1,1意味着只是字段 1。b如果您有前导空格并想忽略它,这是必要的。排序语法很奇怪。这是在POSIX 重新设计它以使其变得合理之后。如果您曾经编写过一个看起来并不复杂的排序命令,那么它可能没有执行您想要的操作。
添加--debug到您的排序命令以查看它用作键的内容。使用包含这些行的示例文件:
ADBC|Banks
ADB|Banks
ADBC|Banks
Run Code Online (Sandbox Code Playgroud)
您可以看到各种-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
____
Run Code Online (Sandbox Code Playgroud)
现在你可能想知道-s我扔在那里的东西。没有它,将整行作为字符串进行默认的最后比较,这适用于具有相等键的行。这通常不是问题,您可能不需要使用-s. 只是在使用时--debug,最后的比较使列表变得混乱,所以我喜欢用-s它来摆脱它。