我想使用公共列加入 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加入我的文件,但我不知道适当的命令 有人可以帮助我,或者指导我找到合适的资源吗?
答案 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。非常方便。