![如何匹配两个文件之间的多列?](https://linux22.com/image/177472/%E5%A6%82%E4%BD%95%E5%8C%B9%E9%85%8D%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E4%B9%8B%E9%97%B4%E7%9A%84%E5%A4%9A%E5%88%97%EF%BC%9F.png)
我有两个文件,我试图匹配多列的信息并输出到一个新文件。我发现了几篇文章,这些文章已经让我得到了大约 80% 的解决方案,并且我正在寻求有关最后一块拼图的帮助。我目前使用的系统是Solaris Unix系统,并且主要使用ksh shell来完成大部分信息操作。我得到的解决方案是使用 awk 命令。这些表目前分为 4 列,并用空格分隔。文件 1 是我保留的主文件列表的一个示例,我将其与文件 2 进行比较。
文件 1 看起来像这样(主文件列表):
FOO1 BAR1 100 SX2000
FOO1 BAR1 101 SX2001
FOO1 BAR1 102 SX2002
FOO1 BAR1 103 SX2003
FOO1 BAR1 104 SX2004
FOO1 BAR1 105 SX2005
FOO1 BAR1 106 SX2006
FOO1 BAR1 107 SX2007
FOO1 BAR1 108 SX2008
FOO1 BAR1 109 SX2009
FOO1 BAR1 110 SX2010
FOO1 BAR1 111 SX2011
FOO1 BAR1 112 SX2012
FOO1 BAR1 113 SX2013
FOO1 BAR1 114 SX2014
FOO1 BAR1 115 SX2015
FOO1 BAR1 116 SX2016
FOO1 BAR1 117 SX2017
FOO1 BAR1 118 SX2018
FOO1 BAR1 119 SX2019
FOO1 BAR1 120 SX2020
文件2看起来像这样(我正在填写的表):
FOO1 BAR1 100 SX
FOO1 BAR1 101 SX
FOO1 BAR1 102 SX
FOO1 BAR1 103 SX
FOO1 BAR1 104 SX
FOO1 BAR1 105 NV
FOO1 BAR1 106 SX
FOO1 BAR1 107 SX
FOO1 BAR1 108 SX
FOO1 BAR1 109 SX
FOO1 BAR1 113 SX
FOO1 BAR1 114 SX
FOO1 BAR1 115 NV
FOO1 BAR1 116 SX
FOO1 BAR1 117 SX
FOO1 BAR1 118 SX
FOO1 BAR1 119 SX
我想要的是这样的结果:
FOO1 BAR1 100 SX2000
FOO1 BAR1 101 SX2001
FOO1 BAR1 102 SX2002
FOO1 BAR1 103 SX2003
FOO1 BAR1 104 SX2004
FOO1 BAR1 105 NV
FOO1 BAR1 106 SX2006
FOO1 BAR1 107 SX2007
FOO1 BAR1 108 SX2008
FOO1 BAR1 109 SX2009
FOO1 BAR1 113 SX2013
FOO1 BAR1 114 SX2014
FOO1 BAR1 115 NV
FOO1 BAR1 116 SX2016
FOO1 BAR1 117 SX2017
FOO1 BAR1 118 SX2018
FOO1 BAR1 119 SX2019
正如您所看到的,我想将文件 2 与文件 1 进行比较,如果完全匹配,则打印出第 4 列中的值。到目前为止,我编写的代码允许我比较两个文件的前 3 列,然后跨第 4 列进行复制。
这是我迄今为止所拥有的脚本的示例:
#! /bin/ksh
file1=master_table
file2=test_table
file3=combined_table
awk -F' ' '(FNR==NR) {a[$1,$2,$3]=$4; next} (($1,$2,$3) in a) {print $1,$2,$3,a[$1,$2,$3]}' $file1 $file2 > $file3
我正在寻找一种方法来仍然与前 3 列进行比较,并在复制信息之前检查第 4 列的前 2 个字符是否匹配。否则,我想从第二个文件复制原始第 4 列值。虽然我目前使用 awk,但这不一定是最终的解决方案。我只想将其保留在 shell 脚本中,因为它使我可以更轻松地对文件进行其他操作。
先谢谢您的帮助!!
答案1
$ cat tst.awk
{ key = $1 FS $2 FS $3 FS substr($4,1,2) }
NR==FNR { a[key]=$4; next }
key in a { $4=a[key] }
{ print }
。
$ awk -f tst.awk file1 file2
FOO1 BAR1 100 SX2000
FOO1 BAR1 101 SX2001
FOO1 BAR1 102 SX2002
FOO1 BAR1 103 SX2003
FOO1 BAR1 104 SX2004
FOO1 BAR1 105 NV
FOO1 BAR1 106 SX2006
FOO1 BAR1 107 SX2007
FOO1 BAR1 108 SX2008
FOO1 BAR1 109 SX2009
FOO1 BAR1 113 SX2013
FOO1 BAR1 114 SX2014
FOO1 BAR1 115 NV
FOO1 BAR1 116 SX2016
FOO1 BAR1 117 SX2017
FOO1 BAR1 118 SX2018
FOO1 BAR1 119 SX2019