比较两个文件中的数据并在 Shell 中更新第二个文件

比较两个文件中的数据并在 Shell 中更新第二个文件

我需要比较两个文件中的数据,并根据需要更新 Shell 中的第二个文件的条件。

我有两组文件。

第一个文件包含的数据为

NUMBER,ID
748378,9508
473738,7892
473832,7839

第二个文件包含的数据为

pk,Name,Number,Code
1,Michael,748378,6373
2,Rachael,747477,7473

我想做的是更新第二个文件,就好像第二个文件中的 pk 不等于 1 并且第一个文件中的数字等于第二个文件中的数字,然后设置文件 2 中的代码 = 文件 1 中的 ID。

我在 shell 中处理这个逻辑时遇到了麻烦。

答案1

MS Excelvlookup可以快速/轻松地解决此问题。

如果 Excel 不适合您,我会合并 awk/sed/shell:

awk -F, '{if ($1 != 1 && $1 ~ /[0-9]+/) {print "sed -i \x27s#" $3 ",[0-9]*#" $3 "," $4 "#\x27 file1.txt"}}' file2.txt | bash

就像马蒂亚斯提到的,如果我正确理解了初衷:

仅当 file2 中的 pk 不为 1 时,才将修复应用于 file1。

在这种情况下,您没有匹配项,因为 file2 中的“pk1 number748378”是 file1 中找到的唯一匹配项,并且当 pk 为 1 时您将排除修复。

在我提供的单行代码中,更改if ($1 != 1if ($1 != 2以查看结果。

awk/sed/bash 合并的说明:

awk -F,-F 表示使用后面的任何内容作为分隔符,在本例中,使用,

if ($1 != 1 && $1 ~ /[0-9]+/)如果字段 1$1不等于 1 并且如果字段 1 是数字,则应用以下 awk 过程。$1 ~ /reg_exp/awk正则表达式语法。

print "sed -i \x27s#" $3 ",[0-9]*#" $3 "," $4 "#\x27 file1.txt"用于awk打印sed命令以将修复应用到 f​​ile1.txt。 $3是 NUMBER 是$4是 file2.txt 中的代码。是打印的\x27十六进制代码。awk'

本质上,使用awk查找 file2 中的字段 3 和 4 并使用sed生成命令,将 file1 中的数字替换为 提供的结果awk,然后sed通过bash(或您拥有的任何其他 shell)运行生成的命令

答案2

我想这就是你想要的脚本:

awk '
    BEGIN { FS=OFS="," }
    NR==FNR {
        map[$1] = $2
        next
    }
    ($1 != 1) && ($3 in map) {
        $4 = map[$3]
    }
    { print }
' file1 file2

但示例输入中的任何行看起来都不符合您指定的条件,因此不会更改任何行,因此根据您提供的内容,无法对其进行测试。

答案3

以下 Perl 脚本可以完成您想要的操作:

#!/usr/bin/env perl
#
use strict;
use warnings;

my $file1 = shift;

my %ids_by_number;

if ($file1 && open(my $f1, "<", $file1)) {
  my ($number,$id) = split(/,/,<$f1>);
  while (<$f1>) {
    my ($number,$id) = split(/,/);
    $ids_by_number{$number} = $id;
  }
}
else {
  print "please provide file1 on the command line\n";
  exit 1;
}

while (<>) {
  my ($ok,$name,$number,$code) = split(/,/);
  if ("1" ne $ok && exists($ids_by_number{$number})) {
    print join(",",$ok,$name,$number,$ids_by_number{$number}),"\n";
  }
  else {
    print $_;
  }
}

不幸的是,您的示例不包含与我理解的条件相匹配的行。因此,我针对以下文件对其进行了测试:

pk,Name,Number,Code
1,Michael,748378,6373
2,Rachael,747477,7473
3,Raffael,473738,1234

您可以在命令行中使用两个文件名调用脚本:

$ ./update file1 file2

或者将 file2 提供给 STDIN:

$ ./update file1 file2

这两个调用都会在 STDOUT 上产生以下输出:

pk,Name,Number,Code
1,Michael,748378,6373
2,Rachael,747477,7473
3,Raffael,473738,7892

相关内容