【问题标题】:join in bash like in SAS像在 SAS 中一样加入 bash
【发布时间】:2012-01-13 00:36:12
【问题描述】:

我想在 bash 中使用一个公共列连接两个文件。我想保留两个文件中所有可配对和不可配对的行。不幸的是,使用join 我只能从一个文件中保存不可配对的字段,例如。 join -1 1 -2 2 -a1 -t" ".
我还想保留两个文件中重复条目(在连接列中)的所有配对。 IE。如果 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 中加入我的文件,但我不知道合适的命令。
有人可以帮助我,或指导我找到适当的资源吗?

【问题讨论】:

  • SAS 的最大可变长度为 32767 个字符。因此,如果您遇到截断问题并且您的文件没有比这更宽,那么就会出现其他问题。您可能需要将 lrecl=32767 语句添加到您的文件名或 infile 语句中。
  • 我使用了导入向导,在其中可以指定“猜测行数”的字段,SAS 在导入期间扫描这些行并根据找到的最长记录分配变量的长度。我会尝试使用代码和您的建议导入。

标签: bash join sas


【解决方案1】:

根据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

【讨论】:

  • 这几乎是完美的解决方案。几乎 - 因为需要指定列。我的真实文件分别有 15 列和 4 列。所以规范不是很方便。但是有效,所以我接受您的回复 - 谢谢。
【解决方案2】:

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

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

请注意,使用 sqlite,您可以利用 index 使连接更加更快

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 是免费且多平台的。非常方便。

【讨论】:

  • 我不喜欢为每一项任务都安装新软件,但谁知道呢,也许如果我必须进行多次合并,它会有所帮助。
  • @MaciejJończyk:sqlite 小巧方便。无论如何都值得拥有:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 2021-01-19
  • 2019-12-20
  • 1970-01-01
  • 2021-03-28
  • 2020-06-05
相关资源
最近更新 更多