2つのファイルのデータを比較し、シェルの2番目のファイルを更新します。

2つのファイルのデータを比較し、シェルの2番目のファイルを更新します。

2つのファイルのデータを比較し、必要に応じてシェル内の2番目のファイルの条件を更新する必要があります。

2セットのファイルがあります。

最初のファイルにはデータが含まれています。

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

2番目のファイルにはデータが含まれています。

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

私がしたいのは、2番目のファイルのpkが1ではなく、1番目のファイルの数が2番目のファイルの数と同じように2番目のファイルを更新してから、ファイル2 =ファイル1にコードを設定することです.の身分証明書です。

シェルでこのロジックを処理する際に問題があります。

答え1

MS Excelはvlookupこの問題をすばやく簡単に解決できます。

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

Matthiasが述べたように、元の意図を正しく理解している場合は、次のようになります。

file2 の pk が 1 でない場合にのみ、file1 にリカバリが適用されます。

この場合、file2の「pk1 number748378」はfile1で見つかった唯一の一致であるため、一致はなく、pkが1の場合は修正を除外します。

私が提供した1行のコードで結果を表示するには、にif ($1 != 1変更します。if ($1 != 2

awk/sed/bash マージガイドライン:

awk -F,-F は、次のものを区切り文字として使用することを意味します。この場合は、次を使用します。,

if ($1 != 1 && $1 ~ /[0-9]+/)field1 が$11 ではなく、field1 が数値の場合、次の awk プロシージャが適用されます。正規表現構文$1 ~ /reg_exp/です。awk

print "sed -i \x27s#" $3 ",[0-9]*#" $3 "," $4 "#\x27 file1.txt"file1.txtに修正を適用するコマンドを awk印刷するために使用されます。例 NUMBER 例は file2.txt のコードです。印刷された16進コード。sed$3$4\x27awk'

awkデフォルトでは、file2で検索フィールド3と4を使用し、sedgenerateコマンドを使用し、file1の数字を指定された結果に置き換えてからawk(または持っている他のシェル)sedbash生成されたコマンドを実行します。

答え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

2つのファイル名を使用してコマンドラインからスクリプトを呼び出すことができます。

$ ./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

関連情報