File1:
X
X
P
X
N
X
Q
File2:
P 1
N 5
Q 0
Desired output:
X 0
X 0
P 1
X 0
N 5
X 0
Q 0
我已经尝试了很多在 bash 上使用合并命令的方法。我无法让它发挥作用。
答案1
Awk
您可以非常轻松地做到这一点!
awk 'FNR==NR{ hash[$1]=$2; next}{ if ($0 in hash) $2 = hash[$1]; else $2 = "0" }1' file2 file1
Awk
通过处理输入行来工作一一次。还有一些特殊的子句Awk
提供BEGIN{}
并END{}
包含在文件处理之前和之后要运行的操作。文件中的每一行根据特殊变量的值FS
(默认一个或多个空格)进行分割,并且可以从$1
, $2
..访问这些单独的字段。$NF
因此,该部分FNR==NR
旨在处理命令中提供的第一个文件参数,因为FNR
跟踪组合文件和NR
当前文件的行号。因此,对于$1
第一个文件中的每个值,这些值都会被散列到调用的数组中hash
,然后当下一个文件处理发生时,该部分将映射散列索引所在位置的$0 in hash
那些行。对于此类映射线,我们打印它们的等效值,对于非映射线,我们打印。file1
file2
0
这{..}1
是一种简写表示,用于{..; print}
根据对各个字段或任何所述特殊变量的修改来基本上重建/打印整行。
查看更多控制 awk 的内置变量
答案2
您可以使用 来执行此操作sed
,但是Gnu
编辑器的版本可以使正则表达式的噪音更少。
基本思想是首先读取 File2 并将其存储在保留空间中,其各行以换行符分隔。
然后我们读取 File1 并将 File2 中的行附加到刚刚读取的 File1 行上。如果我们能够检测到 File1 行在保留空间中的存在,那么就可以了,我们可以通过修剪其他内容的模式空间来按原样打印 File2 行。
否则,我们打印 File1 行并附加 0。
$ sed -Ee '
/ /{H;d;}
G
s/^(\S+)\n.*\n(\1 \S+)(\n.*)?$/\2/;t
s/\n.*/ 0/
' File2 File1