Join 命令给出了错误的输出?

Join 命令给出了错误的输出?

我正在尝试在 Solaris 5.8 版本中加入两个简单文件,如下所示:

~/temp/s: cat 1
work1 a 8058 51
work2 b 15336 51

~/temp/s: cat 2
8058 77-11:29:32 /apps/sas
15336 100-12:23:49 /local/hotfix

~/temp/s: join -1 3 -2 1 1 2
8058 work1 a 51 77-11:29:32 /apps/sas (The other line is missing from the output)

输出只包含一条记录,而它应该是两条记录。我真的不确定哪里出了问题。

有什么办法可以获取输出中的所有记录吗?

答案1

连接键必须按词法排序。

因此,请使用支持进程替换的 shell(ksh93、zsh、bash)并且:

join -1 3 -2 1 <(sort -k 3,3 1) <(sort -k 1,1 2)

或者使用 POSIX/Bourne shell:

sort -k 3,3 1 | {
  sort -k 1,1 2 | join -1 3 -2 1 /dev/fd/3 -; } 3<&0

它有助于理解如何join 工作。join逐行同时读取文件并比较连接键,如果它们相同,我们就得到了匹配并输出结果,如果 key1 < key2,则继续读取 file1 直到 key1 等于 key2 (或更大,在这种情况下我们开始读取 file2 等等)。

这就解释了为什么如果文件不按键排序它就不起作用。

join请注意,除了作为扩展之外,每个都是这种情况,join只要键匹配,GNU 就不会抱怨。但是,如果行未按键排序,则在第一次不匹配时,它会像其他情况一样失败。

答案2

我认为这可能是一个错误join。我刚刚在 Fedora 14 上使用以下版本进行了尝试join

$ join --version
join (GNU coreutils) 8.5

例子

$ join -1 3 -2 1 1 2
8058 work1 a 51 77-11:29:32 /apps/sas
15336 work2 b 51 100-12:23:49 /local/hotfix

选择

你可以用awk这样做:

$ awk 'NR==FNR{_[$3]=$3;next}$1 in _{print _[$1],$0}' 1 2
8058 8058 77-11:29:32 /apps/sas
15336 15336 100-12:23:49 /local/hotfix

相关内容