bash - 合并公共列上的两个文件并使用 awk 打印所有列
问题描述
我有两个很长的空格分隔文件,看起来像这样:
文件1:
CHR SNP A1 A2 MAF
1 rs12 A G 0.43
1 rs1 A T 0.22
1 1:30 G A 0.012
1 rs23 G A 0.012
文件2:
SNP CHR A1 A2 MAF CHR:BP
rs21 1 G A 0.03 1:30
rs13 1 T A 0.06 1:122
rs23 1 A G 0.02 1:234
当文件 1 中的第 2 列与文件 2 中的第 1 列或文件 2 中的第 6 列匹配时,我想将它们合并在一起,并打印两个文件中的所有列。
所以我的示例输出应该是:文件 3
SNP CHR A1 A2 MAF CHR:BP CHR SNP A1 A2 MAF
rs21 1 G A 0.03 1:30 1 1:30 G A 0.012
rs23 1 A G 0.02 1:234 1 rs23 G A 0.012
我使用了以下代码:
awk 'NR==FNR{a[$2]=$0;next} ($1 in a || $6 in a){print $0 FS a[$2]}' file1 file2 > file3
但由于某种原因,它会过滤掉正确的行,但只打印 file2 的列,而不是 file1 的列。
我也尝试过加入,但它给了我奇怪的结果,即使文件已排序。奇怪的意思是,它省略了两个文件中实际存在的大约 1/5 的行。但只是为了完成,这是我尝试使用 join 的代码:
join -1 2 -2 1 -o '2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 1.1 1.2 1.3 1.4 1.5 1.6' <(sort -k2 file1) <(sort -k1 file2) > file3.1
join -1 2 -2 6 -o '2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 1.1 1.2 1.3 1.4 1.5 1.6' <(sort -k2 file1) <(sort -k6 file2) > file3.2
cat file3.1 file 3.2 > file3
有人看到我的错误吗?我会非常感激的。谢谢!
解决方案
您的错误在您的print
命令中:
{print $0 FS a[$2]}
应该
{print $0, ( $1 in a ? a[$1] : a[$6] )}
因为(1)“有趣”字段仅在$2
您处于 file1 时出现,而不是在您 traverse时出现file2
,并且(2)您需要根据您的任一条件从数组中提取数据。我们可以使用经典的三元运算符选择哪个数组元素。(为了便于阅读,我添加了额外的间距。)
请注意逗号的使用,它通过 分隔字段OFS
,而不是使用FS
which 是您的输入字段分隔符。
否则,您的代码对我来说看起来不错。
推荐阅读
- android - 发布版本改造 api 中的 minifyEnabled true 和 shrinkResources true 不起作用
- unit-testing - 如何使用返回 Observable 的 Kotlin lambda 调用测试方法?
- python - 试图从以前的字典中嵌套字典
- matlab - 给定每一行的列索引,如何从矩阵的每一行中选择一个元素?
- python - 使用python连续处理日志文件并提取所需数据
- typescript - 如何在 TypeScript 中正确合并来自 NPM 模块的接口?
- reactjs - 持久复选框位置
- android - 如何通过 Android 应用程序向 Google IoT 核心创建设备?
- javascript - 在提交 JavaScript 时重定向到另一个页面
- javascript - 从d3中的节点获取转换