Awk 匹配两个文件中的值并替换选定列中的值

Awk 匹配两个文件中的值并替换选定列中的值,awk,Awk,如果file1中的列1、2和5的值与file2中的列1、2和9匹配 然后使用file1第3,4列的信息替换file2第1,2列中的值 在输出文件中,为替换的行添加字符R,为未替换的行添加字符O。还为匹配的记录添加file1中的第1列和第2列 file1 37267.00 37181.00 37267.00 37181.00 2605 37269.00 37181.00 37267.00 37184.00 2605 37271.00 37181.00 37271.00

如果file1中的列1、2和5的值与file2中的列1、2和9匹配

然后使用file1第3,4列的信息替换file2第1,2列中的值

在输出文件中,为替换的行添加字符R,为未替换的行添加字符O。还为匹配的记录添加file1中的第1列和第2列

file1

37267.00  37181.00  37267.00  37181.00  2605  
37269.00  37181.00  37267.00  37184.00  2605  
37271.00  37181.00  37271.00  37181.00  2603  
36829.00  37185.00  36820.00  37184.00  2605  
36831.00  37187.00  36831.00  37185.00  2605  
36833.00  37189.00  36833.00  37189.00  2605  
36835.00  37191.00  36831.00  37194.00  2606
37267.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605
37269.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605
37271.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2603
36829.00  37185.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36831.00  37187.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36833.00  37189.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36835.00  37191.00  8640   36840.00  37260.00  37146.00  37624.00  36  2606
file2

37267.00  37181.00  37267.00  37181.00  2605  
37269.00  37181.00  37267.00  37184.00  2605  
37271.00  37181.00  37271.00  37181.00  2603  
36829.00  37185.00  36820.00  37184.00  2605  
36831.00  37187.00  36831.00  37185.00  2605  
36833.00  37189.00  36833.00  37189.00  2605  
36835.00  37191.00  36831.00  37194.00  2606
37267.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605
37269.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605
37271.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2603
36829.00  37185.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36831.00  37187.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36833.00  37189.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605
36835.00  37191.00  8640   36840.00  37260.00  37146.00  37624.00  36  2606
所需输出

37267.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605  O 37267.00  37181.00
37267.00  37184.00  8424   36840.00  37260.00  37146.00  37612.00  36  2605  R 37269.00  37181.00
37271.00  37181.00  8424   36840.00  37260.00  37146.00  37612.00  36  2603  O 37271.00  37181.00
36820.00  37184.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605  R 36829.00  37185.00
36831.00  37185.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605  R 36831.00  37187.00
36833.00  37189.00  8640   36840.00  37260.00  37146.00  37624.00  36  2605  O 36833.00  37189.00
36831.00  37194.00  8640   36840.00  37260.00  37146.00  37624.00  36  2606  R 36835.00  37191.00
我试过了

awk '
FNR==NR{
  a[$1 $2 $5]=$3 $4
  b[$3 $4]=$3
  c[$3 $4]=$4
  next
}
($1 in a){
  $1=b[$1]
  $2=c[$1]
  $1=a[$1]
  found=1
}
{
  $0=found==1?$0",R":$0",O"
  sub(/^...../,"&,")
  $1=$1
  found=""
}
1
' FS=" " file1 FS=" " OFS=" " file2
提前感谢

编辑:,因为OP已经更改了输入文件的样本数据,所以现在添加此解决方案

awk '
FNR==NR{
  a[$3,$4,$5]=$3
  b[$3,$4,$5]=$4
  next
}
{
  val=$1 SUBSEP $2 SUBSEP $9
  val_last=$1 OFS $2
}
(val in a){
  $2=b[val]
  $1=a[val]
  print $0,"R",val_last
  next
}
{
  print $0,"O",val_last
}'  Input_file1  Input_file2  | column -t


似乎您显示的预期输出与您解释的条件不匹配,如果是这种情况,请尝试以下操作(仅使用您显示的样本进行测试)

为什么OP的代码不起作用:因为一旦
$1
我从Input\u file1更改了,那么下一个元素就无法设置,因为当前行的$1值现在更改为Input\u file1的$1。

编辑:因为OP更改了Input\u file的示例数据,所以现在添加此解决方案

awk '
FNR==NR{
  a[$3,$4,$5]=$3
  b[$3,$4,$5]=$4
  next
}
{
  val=$1 SUBSEP $2 SUBSEP $9
  val_last=$1 OFS $2
}
(val in a){
  $2=b[val]
  $1=a[val]
  print $0,"R",val_last
  next
}
{
  print $0,"O",val_last
}'  Input_file1  Input_file2  | column -t


似乎您显示的预期输出与您解释的条件不匹配,如果是这种情况,请尝试以下操作(仅使用您显示的样本进行测试)

为什么OP的代码不起作用:因为一旦
$1
我从Input\u file1更改了,那么下一个元素就无法设置,因为当前行的$1值现在更改为Input\u file1的$1。

在gnu awk上尝试过

 awk 'NR==FNR{r[NR]=$0;next} {x=split(r[FNR],a);if(a[1]==$1&&a[2]==$2&&a[5]==$9){$1=a[3];$2=a[4];print $0,"R",a[1],a[2]} else {print $0,"O",a[1],a[2]}}' file1 file2
在gnu awk上试用

 awk 'NR==FNR{r[NR]=$0;next} {x=split(r[FNR],a);if(a[1]==$1&&a[2]==$2&&a[5]==$9){$1=a[3];$2=a[4];print $0,"R",a[1],a[2]} else {print $0,"O",a[1],a[2]}}' file1 file2

我相信您的预期输出不清楚,请修复它。我们在过去肯定讨论过
abc
=
abc
abc
=
abc
,所以您不应该只是串联像
b[$3$4]
这样的字段来尝试创建唯一的数组索引,您应该使用subsp(或类似的,如果必要的话)相反-
b[$3,$4]
。我相信您的预期输出不清楚,请修复它。我们在过去肯定讨论过
a bc
=
abc
ab c
=
abc
所以您不应该只是连接像
b[$3$4]
这样的字段来尝试创建唯一的数组索引,您应该使用subsp(或类似,如有必要)改为-
b[$3,$4]
.RavinderSingh13,代码有效,但在列的末尾总是写R,?,另外请注意,我对输出文件做了一些更改,添加了文件1中的列1和列2,以匹配records@OXXO,我已经根据您的新样本添加了编辑解决方案。请注意,对于打印
R
的事情,它正在发生,因为在您显示的样本中所有条件都满足(意味着输入文件1中的所有
$1、$2、$5
看起来与输入文件2中的
$1、$2、$9
相同),尝试更改样本位,它将打印
O
我以前也测试过它。请让我知道。RavinderSingh13,它现在工作得很好,所有记录中只有R的问题。我希望R仅适用于已进行替换的行,以识别已更改的行。@OXXO,如前所述,这是因为您的条件在所有显示的示例的会议上,我对文件2的最后一行做了一个小改动,看到它正在打印输出为
36835.00 3719121.00 8640 36840.00 37260.00 37146.00 37624.00 36 2606 O 36835.00 3719121.00
让我知道?RavinderSingh13,是否有可能将Input_文件1中的$3、$4、$5与Input_文件2中的$1、$9进行比较设置输出文件中修改的列$1、$2的值所在的行。然后可能是R和O选项起作用。RavinderSingh13,代码起作用,但在列末尾始终写入R,?,另外,请注意,我对输出文件做了一些更改,从文件1添加了列1和列2,以便匹配records@OXXO,我已根据添加了编辑解决方案您的新示例。请注意,对于打印
R
的事情,它正在发生,因为在您显示的示例中,所有条件都满足(意味着输入文件1中的所有
$1、$2、$5
)看起来与输入文件2中的
$1、$2、$9
相同),尝试更改样本位,它将打印
O
我以前也测试过它。请让我知道。RavinderSingh13,它现在工作得很好,所有记录中只有R的问题。我希望R仅适用于已进行替换的行,以识别已更改的行。@OXXO,如前所述,这是因为您的条件在所有显示的示例的会议上,我对文件2的最后一行做了一个小改动,看到它正在打印输出为
36835.00 3719121.00 8640 36840.00 37260.00 37146.00 37624.00 36 2606 O 36835.00 3719121.00
让我知道?RavinderSingh13,是否有可能将Input_文件1中的$3、$4、$5与Input_文件2中的$1、$9进行比较设置输出文件?中修改的列$1、$2的值所在的行。然后,也许R和O选项可以工作。