2012-01-12 27 views
3

我想加入bash中的两个文件。我想保留这两个文件中的所有可配对和不可配对的行。不幸的是使用join我可以从一个文件中保存不可配对的字段,例如。 join -1 1 -2 2 -a1 -t" "
我也想保留所有配对重复条目(在连接列)从这两个文件。 也就是说如果file1
X ID1 AB
X ID1 CD
X ID1 DF
X id2的CX
X ID3 FV
像SAS一样加入bash

和第二文件是

ID1 DF CF
ID1 DS DG
id2 cv df
id2 as ds
id3 cf cg

生成的文件应该是:

X ID1 AB DF CF
X ID1 AB DS DG
X ID1 CD DF CF
X ID1 CD DS DG
X ID1 DF DF CF
X ID1 DF DS DG
X ID2 CX CV DF
X ID2 CX作为DS
X ID3 FV CF CG

这就是为什么我一直使用SAS做出这样的加入,适当的排序列后。

data x;
merge file1 file2;
by common_column;
run;

它工作正常,但
1.我使用Ubuntu的大部分时间,我切换到Windows在SAS数据合并。
2.最重要的是,SAS可以截断太长的数据条目。

这就是为什么我更愿意以bash加入我的文件,但我不知道适当的命令。
有人可以帮我,或指导我适当的资源吗?

+2

SAS的最大可变长度为32767个字符。所以,如果你遇到截断问题,你的文件不是那么宽泛,那么别的东西就出错了。您可能需要将'lrecl = 32767'语句添加到您的文件名或infile语句中。 – 2012-01-12 17:27:42

+0

我已经使用了导入向导,我可以在其中指定“猜测行数”的字段,导入期间SAS会扫描此行并根据找到的最长记录分配变量的长度。我会尝试使用代码和您的建议导入。 – boczniak767 2012-01-12 21:30:23

回答

4

根据join的手册页,-a <filenum>保留文件<filenum>(1或2)中的所有不可配对的行。所以,只需在您的命令行中添加-a1 -a2即可完成。例如:

# cat a 
1 blah 
2 foo 

# cat b 
2 bar 
3 baz 

# join -1 1 -2 1 -t" " a b 
2 foo bar 

# join -1 1 -2 1 -t" " -a1 a b 
1 blah 
2 foo bar 

# join -1 1 -2 1 -t" " -a2 a b 
2 foo bar 
3 baz 

# join -1 1 -2 1 -t" " -a1 -a2 a b 
1 blah 
2 foo bar 
3 baz 

这是你在找什么?

编辑:

既然你提供更详细,这里是如何产生的所需输出(注意,我的文件a是你的第一个文件,我的文件b你的第二个文件,我不得不扭转-1 1 -2 2到-1 2 -2 1加入id)。我添加了一个字段列表来格式化输出 - 注意'0'是其中的连接字段:

# join -1 2 -2 1 -o 1.1,0,1.3,1.4,2.2,2.3 a b 

产生你给出的。添加-A1-A2保留两个文件,那么你得到两行unpairable线(你可以猜到他们从我的测试数据):

x id4 u t 
id5 ui oi 

这是相当不可读的,因为任何离开了现场只是一个空间。因此,让我们用替换它们“ - ”,导致:

# join -1 2 -2 1 -a1 -a2 -e- -o 1.1,0,1.3,1.4,2.2,2.3 a b 
x id1 a b df cf 
x id1 a b ds dg 
x id1 c d df cf 
x id1 c d ds dg 
x id1 d f df cf 
x id1 d f ds dg 
x id2 c x cv df 
x id2 c x as ds 
x id3 f v cf cg 
x id4 u t - - 
- id5 - - ui oi 
+0

这几乎是完美的解决方案。几乎 - 因为需要列的规格。我的真实文件分别有15列和4列。所以说规范不是很方便。但工作,所以我接受你的回应 - 谢谢。 – boczniak767 2012-01-12 23:27:33

1

如果join命令功能不够强大,我通常使用sqlite如果我需要在外壳执行这样的操作。

您可以轻松地将平面文件导入表格,然后使用正确的JOIN做SQLSELECT

请注意,使用sqlite,您可以利用索引使联接更加快速

sqlite3 << EOF! 
CREATE TABLE my table1 (.... -- define your table here 
CREATE TABLE my table2 (.... -- define your table here 
.separator "," -- define input field separator here if needed 
.import input_file.txt mytable1 
.import input_file.txt mytable2 
SELECT ... JOIN ... 
EOF! 

sqlite是免费的多平台。非常便利。

+0

我不喜欢为每一个任务安装新软件,但是谁知道,也许如果我必须做很多合并,这将是有益的。 – boczniak767 2012-01-12 23:29:39

+0

@MaciejJończyk:sqlite很小且方便。无论如何,这是值得的:-) – 2012-01-12 23:50:16