首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >部分匹配两个不同文件中的单词并提取行sed、awk、grep?

部分匹配两个不同文件中的单词并提取行sed、awk、grep?
EN

Stack Overflow用户
提问于 2018-11-16 08:43:14
回答 1查看 111关注 0票数 1

我有两个不同的文件,我想将第一个文件中的一个数字与另一个文件中的另一个数字部分匹配,然后提取整个列。

File1:

代码语言:javascript
复制
smt_hsa_3150    932
smt_hsa_28592   682
smt_hsa_5184    657
smt_hsa_430 648
smt_hsa_14100   648
smt_hsa_96 648

File2:

代码语言:javascript
复制
chr11 5933549 5933577 29 + hsa_smt_028592
chr11 45693060 45693086 27 - hsa_smt_000059
chr11 45699803 45699832 30 - hsa_smt_000087
chr2 131291172 131291197 26 - hsa_smt_000096

我需要将smt_hsa_28592或28592与hsa_smt_028592或028592相匹配。然后将第二个文件中的行加上第一个文件第二列中的数字提取到一个新文件中。

产出:

代码语言:javascript
复制
chr11 5933549 5933577 29 + hsa_smt_028592 682   
chr2 131291172 131291197 26 - hsa_smt_000096 648

由于我刚开始使用awk/sed编程,我首先尝试将第一个文件的第一列的名称从smt_hsa_3150更改为hsa_smt_3150,但当我执行以下操作时

代码语言:javascript
复制
awk '{gsub("smt","hsa")}1'

然后,我不能使用相同的代码只更改第二个"hsa“。第二个问题是如何将hsa_smt_028592与smt_has_28592或smt_hsa_96与hsa_smt_000096相匹配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-16 09:17:27

为了好玩,使用join:

代码语言:javascript
复制
join -11 -26 -o 2.1,2.2,2.3,2.4,2.5,1.1,1.2 <(awk -F' +|_' '{printf "hsa_smt_%06s %s\n", $3, $4}' file1.txt | sort -k1) <(sort -k6 file2.txt)

awk命令是将file1的第一列格式化为与file2相同的格式。然后我们加入这两个文件(首先我们需要对它们进行排序)。

awk -F' *|_' -> I在多个空格和"_“字符上拆分

'{printf "hsa_smt_%06s %s\n", $3, $4}' -> i将hsa_smt_<第三列打印为宽度6><4 column>的整数。如果需要,Awk将添加前导零

sort -k6 file2awk ... | sort -k1我在第6或第1列对文件进行排序

join -11 -26 -o 2.1,2.2,2.3,2.4,2.5,1.1,1.2 I将文件1 (-11)的第一列和文件2 (-26)的第6列连接起来,然后对这些列(2.1 ->,file2第1列等)进行排序.

纯awk解决方案:

代码语言:javascript
复制
awk 'NR==FNR{split($1,s,"_");smt[s[3]+0]=$2;next}{split($6,s,"_");k=s[3]+0}k in smt{print $0, smt[k]}' file1.txt file2.txt

在这个解决方案中,我拆分了smt_hsa_xxx和hsa_smt_xxx,将第3部分转换为整数,以便比较它们。

NR==FNR{split($1,s,"_");smt[s[3]+0]=$2;next}这个块将只在file1上执行,因为NR==FNR 条件。它拆分第一列,将smt_hsa id转换为整数(在awk中执行+0是将字符串转换为整数的典型方法),然后将第二列存储在名为smt的数组中。

next;阻止为file1执行其他块

{split($6,s,"_");k=s[3]+0}这个块将拆分第6列的file2,将id转换为整数。我们可以使用“+|_”作为分隔符,以避免拆分列(参见第一个解决方案)。

k in smt{print $0, smt[k]}将检查id是否是smt数组的键。然后从file2和file1的第二列(存储在smt中)打印行。

我确信第二种解决方案更有表现力,但在记忆中可能更贪婪。

两者输出相同,行的顺序可能不同:

代码语言:javascript
复制
chr11 5933549 5933577 29 + hsa_smt_028592 682
chr2 131291172 131291197 26 - hsa_smt_000096 648
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53334229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档