使用匹配字符合并两个文件

使用匹配字符合并两个文件
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那些行。对于此类映射线,我们打印它们的等效值,对于非映射线,我们打印。file1file20

{..}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

相关内容