我有两个文本文件zero.txt
和value.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?
答案 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)
使用vim
的一种解决方案 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