linux - awk 将序列与子字符串键结合起来

标签 linux bash awk

我有两个文件用于与制表符分隔的文件合并。 这两个文件 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/

相关文章:

c++ - Eclipse、CDT、(N)Curses 和调试/分析

bash - 如何从 ant 脚本连接文件的所有行?

具有多个条件的 Bash if 语句抛出错误

linux - 括号内的grep内容

linux - 监控控制台输出

c - 在多线程服务器中使用 Pthread

linux - 比较二进制文件以导出文本文件并查找自上次导出后哪些二进制文件已更改或下一个

bash - show-all-if-ambiguous vs show-all-if-unmodified?

bash - 对于两列,如何对按第二列分组的第一列中的值求和?

linux - 在输出中搜索并从特定行搜索到特定行,然后再次搜索