比较两个文件,如果第二个文件中没有值,则添加零

时间:2013-06-08 21:08:53

标签: linux shell unix awk

我有两个文本文件zero.txtvalue.txt

zero.txt:

hour Value1  value2  
0        0       0
1        0       0
2        0       0
3        0       0
4        0       0

高达24。

和value.txt:

hour Value1  value2  
0        1       1
2        2       2
4        3       4 

我想比较两个文件中的第一列(实际上第一列是0-24小时)。如果values.txt具有小时值,我需要在output.txt中打印该行,如果没有值,我需要在output.txt中使用零打印小时。如下所示:

output.txt

hour Value1  value2  
0        1       1
1        0       0
2        2       2
3        0       0
4        3       4 

如何实现这个Unix?

4 个答案:

答案 0 :(得分:4)

这就是你想要的:

$ awk 'NR==FNR{a[$1]=$0;next}($1 in a){print a[$1];next}{print $0}' value zero
hour Value1  value2
0        1       1
1        0       0
2        2       2
3        0       0
4        3       4

<强>解释

awk脚本的结构是conditional{block}形式的一系列条件和块。对于在输入中读取的每个记录执行脚本,如果条件被评估为真,则将执行块中的代码。一个简单的示例是awk '/hour/{print $0}' value,其中输入是文件value,脚本/hour/{print $0}在文件的每一行上执行。这里的条件是字符串hour的正则表达式匹配,因为只有文件中的第一行匹配它才是输出中打印的唯一行。

  • NR是一个特殊的awk变量,对于每个读取的记录都会递增。默认情况下,记录会在awk中的新行上拆分。 FNR几乎相同,但每次读取新文件时都会重置。因此,条件NR==FNR仅在我们读取第一个文件value时才为真。
  • a[$1]=$0正在使用第一个字段作为键创建一个行查找。
  • next抓取文件中的下一行,跳过以下块。
  • 当正在读取第二个文件时,我们检查第一个字段是否是我们从第一个文件($1 in a)创建的查找,如果我们打印该值并获取下一行。
  • 如果第一个字段不是数组中的键,我们会在我们正在查看的文件中打印该行zero

使用一些awk idiums我们可以缩短脚本,但在开始时最好是冗长:

awk 'NR==FNR{a[$1]=$0;next}$1 in a{$0=a[$1]}1' value zero

您应该首先阅读Effective awk programming

答案 1 :(得分:4)

您可以使用join命令。

join -o 1.1,2.2,2.3 -a 1 -e 0 zero.txt value.txt

答案 2 :(得分:1)

使用

的一种解决方案

script.vim的内容:

set backup
buffer 2
2,$ yank 
buffer 1
2 put!
2,$ ! sort -sun -k1,1
saveas! output.txt
qa!

像以下一样运行:

vim -u NONE -N -S script.vim zero.txt value.txt

并将创建一个名为output.txt的文件,内容为:

hour Value1  value2  
0        1       1
1        0       0
2        2       2
3        0       0
4        3       4

它是如何工作的?它会复制values.txt的内容,在zero.txt标题后粘贴所有内容,然后按第一列删除重复项对其进行排序。

答案 3 :(得分:-2)

如果我们忽略标题并使用bash脚本(您需要调整边距):

while read x1 x2 x3
do
    if grep -q "^$x1\>" value.txt
    then
        grep "^$x1\>" value.txt >> output.txt
    else
        echo "$x1      $x2       $x3" >> output.txt
    fi
done < zero.txt