文件 1 包含两列。第 1 列包含代谢途径的名称,第 2 列包含该途径中存在的基因数量:
pathway1 3
pathway2 4
pathway3 5
pathway4 6
pathway5 9
文件 2 有三列。第 1 列包含组编号,第 2 列包含属于特定组的代谢途径名称,第 3 列包含每个途径中存在的基因数量:
group1 pathway1 2
group1 pathway4 5
group1 pathway2 3
group2 pathway2 1
group2 pathway3 2
文件 1 和文件 2 为 csv 格式。
所需输出:
根据路径名称,如何在 File2 第 3 列旁边打印 File1 第 2 列中的基因数量,如下所示:
group1 pathway1 2 3
group1 pathway4 5 6
group1 pathway2 3 4
group2 pathway2 1 4
group2 pathway3 2 5
答案1
这就是这样join
做的目的:
$ join -o 1.1,1.2,1.3,2.2 -12 -21 <(sort -k2 file2) <(sort file1)
group1 pathway1 2 3
group2 pathway2 1 4
group1 pathway2 3 4
group2 pathway3 2 5
group1 pathway4 5 6
或者,如果您的输入文件实际上如您所建议的那样用逗号分隔,但在您的问题中没有显示:
$ join -t, -o 1.1,1.2,1.3,2.2 -12 -21 <(sort -t, -k2 file2) <(sort file1)
group1,pathway1,2,3
group2,pathway2,1,4
group1,pathway2,3,4
group2,pathway3,2,5
group1,pathway4,5,6
join
将在公共字段上连接两个文件的行。设置-o
输出格式。在这里,我告诉它打印第一个文件的字段 1、2 和 3 ( 1.1,1.2,1.3
),然后打印第二个文件的第二个字段 ( 2.2
)。并在每个文件中设置连接字段-1
。-2
因此,-12 -21
意味着“加入 file1 的第二个字段和 file2 的第一个字段”。最后,join
需要排序输入,因此我们在将两个文件传递到join
.
答案2
这在 awk 中应该足够了:
awk 'NR==FNR{a[$1]=$2;next}{print $0,a[$2]}' file1 file2
您的示例文件以空格分隔的形式呈现,上面的代码适用于空格分隔的文件。
如果你的 file1 file2 以逗号分隔,那么你可以这样做:
awk 'BEGIN{FS=OFS=","}NR==FNR{a[$1]=$2;next}{print $0,a[$2]}' file1 file2
PS:在awk中,FS对应于输入字段分隔符,OFS对应于输出字段分隔符。默认的 FS 和 OFS 是“空格”,如果您的情况是空格,则可以省略(即在第一个代码中省略)
如果您想组合不同的输入字段分隔符和不同的输出字段分隔符,那么您可以执行以下操作:
awk 'BEGIN{FS=" ";OFS=","}NR==FNR{a[$1]=$2;next};$1=$1{print $0,a[$2]}' file1 file2
#The $1=$1 part is required to redisign the record according to the different Output Field Separator OFS
空格分隔的输入文件的最后一个代码(正如您的问题中所显示的那样)和以逗号分隔的输出将提供:
group1,pathway1,2,3
group1,pathway4,5,6
group1,pathway2,3,4
group2,pathway2,1,4
group2,pathway3,2,5
PS:对于空格分隔的文件,您可以指定OFS="\t"
(制表符)以获得更美观的输出。
答案3
perl -lane '
if ( @ARGV == 1 ) {
$h{ $F[0] } = $F[1];
} else {
print "$_ $h{ $F[1] }";
}
' file1 file2