我有两个文件用于与制表符分隔的文件合并。 这两个文件 key 可能仅在“读取”数方面不同。
我想比较这两个文件并根据子字符串键和匹配进行组合。
例如,
File1 Key : "Cluster0_Reads255"
File2 Key : "Cluster0_Reads50"
This case is same because "Cluster0_Reads" is identical.
在这种情况下,我想将这两列与 File1 键名组合起来。 请检查以下示例案例。
文件 1。
A B
Cluster0_Reads255 500
Cluster1_Reads253 300
Cluster2_Reads100 200
Cluster3_Reads100 350
文件 2。
A C
Cluster0_Reads50 GE
Cluster1_Reads200 GA
Cluster2_Reads100 GA
结果。
A B C
Cluster0_Reads255 500 GE
Cluster1_Reads253 300 GA
Cluster2_Reads100 200 GA
Cluster3_Reads100 350 -
我制作了一个具有精确匹配查找和组合的 awk,如下所示,
awk '
BEGIN { FS = OFS = "\t" }
{key = $1}
FNR == NR {result[key] = $0; next;}
(key in result) { updated[key]=1 ; for (i=2; i <= NF; i++) result[key] = result[key] FS $i }
END {
PROCINFO["sorted_in"] = "@ind_str_asc" # if using GNU awk
for (key in result) {
if(!(key in updated)) result[key] = result[key] FS "-"
if(!(length(key)==0)) print result[key]
}
}
' File1 File2 > File3
子串后有什么办法可以合并吗?
谢谢。
最佳答案
下面有点肮脏的 awk
脚本可以完成这项工作,但我相信您会在这里找到更好的脚本。
awk -v FS="\t" -v OFS="\t" '
NR==FNR{f1=$1;sub(/[0-9]*$/,"",f1);file1info[f1]=$0;next}
{sub(/[0-9]*$/,"",$1);file2info[$1]=$2}
END{
for(i in file1info){
print file1info[i],(i in file2info)?file2info[i]:"-";
}
}' File1 File2 | expand -t 20 | sort -nk1
输出
A B C
Cluster0_Reads255 500 GE
Cluster1_Reads253 300 GA
Cluster2_Reads100 200 GA
Cluster3_Reads100 350 -
编辑
终于设法得到一个更小更快的。考虑到 file2 的簇始终构成 file1 的子集,技巧是反转文件。
awk -v FS="\t" -v OFS="\t" '
NR==FNR{sub(/[0-9]*$/,"",$1);file2info[$1]=$2;next}
{f1=$1;sub(/[0-9]*$/,"",f1);print $0,(f1 in file2info)?file2info[f1]:"-"}
' File2 File1 | expand -t 20 |sort -nk1
输出
A B C
Cluster0_Reads255 500 GE
Cluster1_Reads253 300 GA
Cluster2_Reads100 200 GA
Cluster3_Reads100 350 -
关于linux - awk 将序列与子字符串键结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39254457/