连接两个文件,每个文件有两列,包括不匹配的行

连接两个文件,每个文件有两列,包括不匹配的行

我正在尝试匹配并合并两组排序数据,每个文件一组。每个文件包含两列:键字段和关联值。生成的输出应包含三列:键字段、第一个文件中的值(如果有)以及第二个文件中的值(如果有)。我需要包含不匹配的数据行。

第一个文件“约翰”

apple,green
cherry,red
orange,orange

第二个文件“简”

apple,red
banana,yellow
cherry,yellow
kiwi,green

期望的结果

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

起初我以为这对我来说是一项微不足道的工作join

LC_ALL=C join -j1 -a1 -a2 -t',' john jane

但结果总是-a1 -a2将不匹配的值放在第二列中:

apple,green,red
banana,yellow
cherry,red,yellow
kiwi,green
orange,orange

我需要能够看到不匹配的值源自哪个源文件,理想情况是通过将这些值放在结​​果文件的适当的第二列或第三列中,但我无法找出一种简单的方法来实现这一点,而不需要深入到awk ... getline()类型构造中。

请问有什么建议吗?

答案1

你要-o auto

join -t, -j 1 -a 1 -a 2 -o auto john jane

man join:

-o FORMAT

    遵守FORMAT在构造输出线时
     ︙
如果FORMAT是关键字' auto',那么每个文件的第一行决定了每行输出的字段数。

或者更好地解释自GNU Coreutils:加入调用 (点击链接进入join 中的常规选项):

' -o auto'

如果指定了关键字“ auto”,则从每个文件的第一行推断输出格式。这与默认输出格式相同,但也确保每行输出相同数量的字段。缺失的字段将被选项替换-e,多余的字段将被丢弃。

% cat john 
apple,green
cherry,red
orange,orange
% cat jane 
apple,red
banana,yellow
cherry,yellow
kiwi,green
% join -t, -j 1 -a 1 -a 2 -o auto john jane
apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

答案2

您可以明确指定输出格式

LC_ALL=C join -o0,1.2,2.2 -j1 -a1 -a2 -t',' john jane

产生

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

这里的关键是,连接字段也可以在输出格式中引用0,这在不可配对行的上下文中非常有用

答案3

这个命令几乎可以做到这一点;如果密钥仅出现在 file1 中,则它会省略尾随逗号。现在没有时间完全调试:

awk -F, 'BEGIN{OFS=","} FNR==NR{val[$1]=$2;next} {val[$1]=val[$1] "," $2}END{for (key in val) {print key, val[key]}}' john jane

输出:

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange

答案4

使用 R 编程语言

将两个数据文件读入R REPL:

> john <- read.csv("/Users/admin/john", header=FALSE, stringsAsFactors=FALSE)
> john
      V1     V2
1  apple  green
2 cherry    red
3 orange orange
>
> jane <- read.csv("/Users/admin/jane", header=FALSE, stringsAsFactors=FALSE)
> jane
      V1     V2
1  apple    red
2 banana yellow
3 cherry yellow
4   kiwi  green

要合并 R REPL 中的数据文件:

> merge(john, jane, by = c("V1"), all=TRUE)
      V1   V2.x   V2.y
1  apple  green    red
2 banana   <NA> yellow
3 cherry    red yellow
4   kiwi   <NA>  green
5 orange orange   <NA>
> 

输出到文件(使用write.table):

> write.table( merge(john, jane, by = c("V1"), all=TRUE), "john_jane.csv", sep=",", quote=F, row.names=F, col.names=F, na="")

生成的文件(“john_jane.csv”):

apple,green,red
banana,,yellow
cherry,red,yellow
kiwi,,green
orange,orange,

从参数中可以看出write.table,<NA> 值设置为带有 的空字符串na=""。如需进一步帮助,请在 R REPL 中的提示符处键入命令,前面加一个问号,如?getwd()?setwd()或。?read.csv()?merge()

[注意:根据 R 安装的年龄,stringsAsFactors=FALSE在每个函数调用中包含参数可能是多余的]。read.csv()

https://www.r-project.org/
https://cran.r-project.org/index.html

相关内容