我该怎么做?
File1看起来像这样:
foo 1 scaf 3
bar 2 scaf 3.3
File2看起来像这样:
foo 1 scaf 4.5
foo 1 boo 2.3
bar 2 scaf 1.00
我想做的是找到同时出现的线条File1 and File2当字段1,2,和3是相同的。
有办法做到吗?
这里是correct答案(就使用标准而言GNU 核心工具工具,而不是编写自定义脚本perl/awk你说出它的名字)。
$ join -j1 -o1.2,1.3,1.4,1.5,2.5 <(<file1 awk '{print $1"-"$2"-"$3" "$0}' | sort -k1,1) <(<file2 awk '{print $1"-"$2"-"$3" "$0}' | sort -k1,1)
bar 2 scaf 3.3 1.00
foo 1 scaf 3 4.5
好的,它是如何工作的:
-
首先我们将使用一个很棒的工具join
它可以合并两条线。join
有两个要求:
- We can join仅由单个字段。
- 两个文件都必须是sorted按关键列!
-
我们需要生成keys在输入文件中,为此我们使用一个简单的awk
script:
$ cat file1
foo 1 scaf 3
bar 2 scaf 3.3
$ <file1 awk '{print $1"-"$2"-"$3" "$0}'
foo-1-scaf foo 1 scaf 3
bar-2-scaf bar 2 scaf 3.3
你看,我们添加了第一列,其中包含一些键,例如“foo-1-scaf”。
我们也做同样的事file2.
BTW. <file awk
,只是一种奇特的写作方式awk file
, or cat file | awk
.
我们也应该sort我们的文件按键,在我们的例子中这是第 1 列,所以我们添加
到命令末尾| sort -k1,1
(sort按第 1 列到第 1 列的文本)
-
此时我们就可以生成文件了文件1.with.key and file2.with.key并加入他们,
但假设这些文件很大,我们不想通过文件系统复制它们。相反,我们可以使用称为bash
过程替代 http://tldp.org/LDP/abs/html/process-sub.html将输出生成到命名管道(这将避免任何
不必要的中间文件创建)。欲了解更多信息,请阅读提供的链接。
我们的目标语法是:join <( some command ) <(some other command)
-
最后一件事是解释花哨的连接参数:-j1 -o1.2,1.3,1.4,1.5,2.5
从这篇文章中吸取的教训应该是:
- 你应该掌握核心工具包,这些工具组合起来非常强大,你几乎永远不需要编写自定义程序来处理此类情况,
- core utils 工具也非常快速且经过严格测试,因此它们始终是最佳选择。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)