Linux awk 合并两个文件

5
我有以下脚本可以合并两个文件。
awk -F"\t" '
    {key = $1}
    !(key in result) {result[key] = $0; next;}
    { 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) print result[key]
    }
' $1 $2 > $3 

第一列是键,$1和$2都是键。 但是如果$2列有一个键而$1列没有,则仍然进行合并,除了$1行。

我只想在$1键存在的情况下进行合并。 如何简单地将这两个文件合并?

例如,

文件1

Key    Column1  Column2  Column3  
Test1    500     400     200               
Test2    499     400     200               
Test5    600     200     150               
Test6    600     199     150               
Test7    599     199     100               

文件2

Key    Column4   Column5
Test1    Good     Good                    
Test2    Good     Good
Test3    Good     Good                    
Test4    Good     Good
Test5    Good     Good                    
Test6    Good     Good
Test7    Good     Good

当前组合

Key    Column1  Column2  Column3  Column4   Column5
Test1    500     400     200       Good     Good     
Test2    499     400     200       Good     Good      
Test5    600     200     150       Good     Good          
Test6    600     199     150       Good     Good          
Test7    599     199     100       Good     Good  
Test3    Good    Good  
Test4    Good    Good  

预期的合并。

Key    Column1  Column2  Column3  Column4   Column5
Test1    500     400     200       Good     Good     
Test2    499     400     200       Good     Good      
Test5    600     200     150       Good     Good          
Test6    600     199     150       Good     Good          
Test7    599     199     100       Good     Good 

谢谢你!

句子“第一列是键,$1和$2都是键。但是如果$2列有一个键,而$1列没有键,则它仍然会合并,除了$1行。”没有任何意义。您应该更改它们以反映您的意思,或者只需将其删除。 - Ed Morton
3个回答

7
你的方法不正确。你所描述的是一个“join”操作,而有一个非常明显的UNIX工具可以完成这个任务: join
$ join file1 file2 | column -t
Key    Column1  Column2  Column3  Column4  Column5
Test1  500      400      200      Good     Good
Test2  499      400      200      Good     Good
Test5  600      200      150      Good     Good
Test6  600      199      150      Good     Good
Test7  599      199      100      Good     Good

或者,如果您坚持使用 awk:

$ awk 'NR==FNR{m[$1]=$2" "$3; next} {print $0, m[$1]}' file2 file1 | column -t
Key    Column1  Column2  Column3  Column4  Column5
Test1  500      400      200      Good     Good
Test2  499      400      200      Good     Good
Test5  600      200      150      Good     Good
Test6  600      199      150      Good     Good
Test7  599      199      100      Good     Good

4

在存储到数组时添加条件

{key = $1}
!(key in result) && NR == FNR {result[key] = $0; next;}
(key in result) { 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) print result[key]
}
NR == FNR 确保我们存储在 result 中的 key 来自第一个文件。 我们还添加了 (key in result) 以确保在我们遍历 for 循环之前该键存在。

4
您可以尝试以下命令:
awk '
    BEGIN { FS = OFS = "\t" }
    {key = $1}
    FNR == NR {result[key] = $0; next;}
    (key in result) { 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) print result[key]
    }
' file1 file2

我已经修改了这些检查。 FNR == NR 只保存第一个文件的 result 行。而 (key in result) 应用于第二个文件,并且仅追加在第一个文件中先前找到的那些键的列。
它产生以下结果:
Key     Column1 Column2 Column3         Column4 Column5
Test1   500     400     200             Good    Good
Test2   499     400     200             Good    Good
Test5   600     200     150             Good    Good
Test6   600     199     150             Good    Good
Test7   599     199     100             Good    Good

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接