从不同的文件加入两列
Join on two columns from seperate files
我有两个文件:
文件 1:
chr1 100736194 46 0.731 + 100735713 100736636
chr1 100736194 49 0.879 + 100735723 100736646
chr1 100736196 54 0.952 + 100735753 100736666
文件 2:
chr1 100735713 100736636 + BMCHAS
chr1 100735723 100736646 + ATCGSG
chr1 100735753 100736666 + BDUSUS
我想加入文件 1 和 2 基于
- file1 的第 6 和第 7 列,以及
- file2 的第 2 列和第 3 列
输出如下内容:
chr1 100736194 46 0.731 + 100735713 100736636 BMCHAS
chr1 100736194 49 0.879 + 100735723 100736646 ATCGSG
chr1 100736196 54 0.952 + 100735753 100736666 BDUSUS
我不知道如何对多个列使用连接,我查找了一个 awk 解决方案并一直在尝试实现它,但我认为我在某个地方不对,我正在使用的命令是: awk 'NR==FNR{a[,]=;next}{=a[,];print}' OFS='\t' file2 file1,
此外,匹配每个文件中的两列而不是一列也很重要,因为单列不够唯一。这意味着我不能使用单列匹配方案,例如只匹配file1的第6列和file2的第2列,它必须使用上面指定的多个列。
提前致谢。
您仍然可以使用 join
。诀窍是将两列连接在一起,以便将它们视为一列。
我在这里用 sed
完成了它,但你可以使用 awk
或任何你喜欢的东西。
<(..)
语法是 bash-specific,意思是大约 "create a temporary named pipe and pass that as a file".
join \
-1 6 \
-2 2 \
-o "1.1 1.2 1.3 1.4 1.5 0 2.4" \
<(sed 's/\([0-9]\{9\}\) *\([0-9]\{9\}\)/-/' file1) \
<(sed 's/\([0-9]\{9\}\) *\([0-9]\{9\}\)/-/' file2) \
| sed 's/-/ /'
这适用于 GNU sed(我有 4.2.2);您可能需要针对其他 sed 实现进行调整。
输入 sed
命令将您的输入文件转换为如下所示:
chr1 100736194 46 0.731 + 100735713-100736636
输出 sed
命令撤消更改。
输出格式(-o "1.1 1.2 1.3 1.4 1.5 0 2.4"
)给出了您要求的输出:
chr1 100736194 46 0.731 + 100735713 100736636 BMCHAS
chr1 100736194 49 0.879 + 100735723 100736646 ATCGSG
chr1 100736196 54 0.952 + 100735753 100736666 BDUSUS
通过 awk
awk ' NR==FNR{ a[ FS ]=;next} ( FS ) in a { print [=10=] FS a[ FS ]} ' file2 file1
我有两个文件:
文件 1:
chr1 100736194 46 0.731 + 100735713 100736636
chr1 100736194 49 0.879 + 100735723 100736646
chr1 100736196 54 0.952 + 100735753 100736666
文件 2:
chr1 100735713 100736636 + BMCHAS
chr1 100735723 100736646 + ATCGSG
chr1 100735753 100736666 + BDUSUS
我想加入文件 1 和 2 基于
- file1 的第 6 和第 7 列,以及
- file2 的第 2 列和第 3 列
输出如下内容:
chr1 100736194 46 0.731 + 100735713 100736636 BMCHAS
chr1 100736194 49 0.879 + 100735723 100736646 ATCGSG
chr1 100736196 54 0.952 + 100735753 100736666 BDUSUS
我不知道如何对多个列使用连接,我查找了一个 awk 解决方案并一直在尝试实现它,但我认为我在某个地方不对,我正在使用的命令是: awk 'NR==FNR{a[,]=;next}{=a[,];print}' OFS='\t' file2 file1,
此外,匹配每个文件中的两列而不是一列也很重要,因为单列不够唯一。这意味着我不能使用单列匹配方案,例如只匹配file1的第6列和file2的第2列,它必须使用上面指定的多个列。
提前致谢。
您仍然可以使用 join
。诀窍是将两列连接在一起,以便将它们视为一列。
我在这里用 sed
完成了它,但你可以使用 awk
或任何你喜欢的东西。
<(..)
语法是 bash-specific,意思是大约 "create a temporary named pipe and pass that as a file".
join \
-1 6 \
-2 2 \
-o "1.1 1.2 1.3 1.4 1.5 0 2.4" \
<(sed 's/\([0-9]\{9\}\) *\([0-9]\{9\}\)/-/' file1) \
<(sed 's/\([0-9]\{9\}\) *\([0-9]\{9\}\)/-/' file2) \
| sed 's/-/ /'
这适用于 GNU sed(我有 4.2.2);您可能需要针对其他 sed 实现进行调整。
输入 sed
命令将您的输入文件转换为如下所示:
chr1 100736194 46 0.731 + 100735713-100736636
输出 sed
命令撤消更改。
输出格式(-o "1.1 1.2 1.3 1.4 1.5 0 2.4"
)给出了您要求的输出:
chr1 100736194 46 0.731 + 100735713 100736636 BMCHAS
chr1 100736194 49 0.879 + 100735723 100736646 ATCGSG
chr1 100736196 54 0.952 + 100735753 100736666 BDUSUS
通过 awk
awk ' NR==FNR{ a[ FS ]=;next} ( FS ) in a { print [=10=] FS a[ FS ]} ' file2 file1