Bash vlookup解决方案

时间:2018-10-29 22:03:35

标签: bash awk sed

我有两个文件,
文件1

2,1,1,1,Test1,1540584051,52
6,5,1,1,Test2,1540579206,54
3,3,0,0,Test3,1540591243,36

文件2

2,1,0,2,Test1,1540584051,52
6,5,0,2,Test2,1540579206,54

我想从文件1中查找第7列的值,以检查它是否与文件2中的第7列的值匹配,并且在匹配时,用文件1中的相应行替换文件2中的该行。 因此输出为

2,1,1,1,Test1,1540584051,52
6,5,1,1,Test2,1540579206,54

谢谢。

2 个答案:

答案 0 :(得分:0)

您可以使用以下脚本进行操作:

BEGIN { FS="," }

NR==FNR {
    lookup[$7] = $0
    next
}

{
    if (lookup[$7] != "") {
        $0 = lookup[$7]
    }
    print
}

END {
    print ""
    print "Lookup table used was:"
    for (i in lookup) {
        print "   Key '"i"', Value '"lookup[i]"'"
    }
}

BEGIN部分仅将字段分隔符设置为,,以便可以轻松处理各个字段。

NRFNR变量分别是 full 输入流(所有文件)的行号和 current < / em>文件在输入流中。当您处理第一个(或唯一一个)文件时,它们是相等的,因此我们将其用作简单地存储来自第一个文件的行(在字段7上键入)的一种方法。

如果NRFNR 相等,那是因为您已经启动了第二个文件,如果它们的键在第一个文件。

这可以通过简单地检查查找表中是否存在具有所需键的行来完成,如果存在,则替换当前行以查找表行。然后我们打印(原始或替换的)行。

END部分仅用于调试目的,它输出已创建和使用的查找表,一旦您满意脚本可以按预期工作就可以将其删除。


您将在下面的成绩单中看到输出,以期说明它 正常工作:

pax$ cat file1
2,1,1,1,Test1,1540584051,52
6,5,1,1,Test2,1540579206,54
3,3,0,0,Test3,1540591243,36

pax$ cat file2
2,1,0,2,Test1,1540584051,52
6,5,0,2,Test2,1540579206,54

pax$ awk -f sudarshan.awk file1 file2
2,1,1,1,Test1,1540584051,52
6,5,1,1,Test2,1540579206,54

Lookup table used was:
   Key '36', Value '3,3,0,0,Test3,1540591243,36'
   Key '52', Value '2,1,1,1,Test1,1540584051,52'
   Key '54', Value '6,5,1,1,Test2,1540579206,54'

如果您希望脚本尽可能“短”地使用它,请使用:

awk -F, 'NR==FNR{x[$7]=$0;next}{if(x[$7]!=""){$0=x[$7]};print}' file1 file2

尽管我自己更喜欢可读的版本。

答案 1 :(得分:0)

这可能对您有用(GNU sed):

sed -r 's|^([^,]*,){6}([^,]*).*|/^([^,]*,){6}\2/s/.*/&/p|' file1 | sed -rnf - file2

将file1转换为sed脚本,并使用第7个字段作为键查找替换file2中匹配的任何行。

在您的示例中,第7个字段是最后一个字段,因此上述解决方案的简称为:

sed -r 's|.*,(.*)|/.*,\1/s/.*/&/p|' file1 | sed -nf - file2