像SAS一样加入bash

时间:2012-01-12 13:37:46

标签: bash join sas

我想使用公共列加入 bash 中的两个文件。我想保留两个文件中所有可配对和不可操作的行。不幸的是,使用join我只能从一个文件中保存不可用的字段,例如。 join -1 1 -2 2 -a1 -t" "
我还想保留两个文件中重复条目(在连接列中)的所有配对。 即如果file1是
x id1 a b
x id1 c d
x id1 d f
x id2 c x
x id3 f v

和第二个文件是

id1 df cf
id1 ds dg
id2 cv df
id2 as ds
id3 cf cg

生成的文件应为:

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

这就是为什么我在排序合适的列之后总是使用 SAS 进行此类连接。

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

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

这就是为什么我更喜欢用bash加入我的文件,但我不知道适当的命令 有人可以帮助我,或者指导我找到合适的资源吗?

2 个答案:

答案 0 :(得分: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以保留两个文件中不可用的行,然后再获得两行(您可以从中猜出我的测试数据):

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

答案 1 :(得分:1)

如果join命令不够强大,我通常会使用sqlite,如果我需要在shell中执行此类操作。

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

请注意,使用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是免费的和mutiplatform。非常方便。