2013-02-27 77 views
1

我一直在使用这一问题的建议: Find value from one csv in another one (like vlookup) in bash (Linux)VLOOKUP风格查询循环(

要尝试并创建一个脚本,我通过多个数据文件,并在VLOOKUP风格的方式添加列从几个其他(单个)的参考文件。

数据文件的例子(*。数据)

info1 7 44567 1 2 marker1 
info2 3 143679 2 2 marker2 

参考文件的例子(ref.txt,文件从查找)

marker1  66% 
marker2  34% 

第二参考文件的例子(ref2.txt,第二文件以从查找)

info1  exact 
info2  partial

输出所需

info1 7 44567 1 2 marker1 66% exact 
info2 3 143679 2 2 marker2 34% partial 

试图环路(仅示出一个参考文件,因为我还没有那个工作呢!)

#!/bin/bash 
for file in `ls /path/*.data`; 
do 
for i in $file; 
do 
KEY=$(cut -f 6 $file); 
    printf "%s\t" $i; 
    grep "${KEY}" /path/ref1.txt | cut -f 2 ; 
done 
done 

我认为我写的脚本存在两个问题 输出当前是每个输入文件一行,而不是输入文件的所有行追加,它是文件的文件名,而不是一行在文件中。虽然参考位似乎正在工作(从我可以告诉单行输出)。 I,E:

/path/1.data 66% 

谁能告诉我什么错误,或者请提出一个聪明的方式来做到这一点? 非常感谢。

回答

2

这里有一个join实用程序。特别是,举个例子:

join -o 1.1,1.1,1.3,1.4,1.5,1.6,2.2 -1 6 -2 1 test.data ref.txt | 
    join -o 1.1,1.1,1.3,1.4,1.5,1.6,1.7,2.2 -j 1 - ref2.txt 

这会产生你的建议输出。 -o <list>选项指定要以<filenumber>.<fieldnumber>格式打印的每个字段。 -1 <n>-2 <n>指定要在每个文件中分别匹配哪个字段,-j <n>是两个文件中字段号相同时可以使用的快捷方式。

+0

这真的很有用,谢谢。比循环复杂得多(虽然乍一看有点令人生畏!) – jksl 2013-02-27 22:27:36

+0

这是一个很多的输入...为了使它更短一点,你可以'join -1 6 -2 1 test.data ref .txt |加入-j 1 - ref2.txt',但输出的顺序与你想要的顺序有所不同。这可以很容易地通过'awk'中的后处理步骤来纠正,或者如果它很重要的话。 – twalberg 2013-02-28 01:59:31

+0

我可以问,这是否排除没有共享密钥的条目?我可能不得不发布另一个问题,但会有一种方法来放置一个空格或0,如果没有条目匹配ref文件中的数据文件?谢谢。 – jksl 2013-02-28 09:12:48