두 파일의 데이터를 비교하고 셸에서 두 번째 파일을 업데이트합니다.

두 파일의 데이터를 비교하고 셸에서 두 번째 파일을 업데이트합니다.

두 파일의 데이터를 비교하고 필요에 따라 셸에서 두 번째 파일의 조건을 업데이트해야 합니다.

두 세트의 파일이 있습니다.

첫 번째 파일에는 데이터가 포함되어 있습니다.

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

두 번째 파일에는 데이터가 포함되어 있습니다.

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

내가하고 싶은 것은 두 번째 파일의 pk가 1이 아니고 첫 번째 파일의 숫자가 두 번째 파일의 숫자와 같은 것처럼 두 번째 파일을 업데이트 한 다음 파일 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일 때 수정 사항을 제외합니다.

제가 제공한 코드 한 줄에서 결과를 보려면 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다음 (또는 가지고 있는 다른 쉘)을 sed통해 bash생성된 명령을 실행합니다.

답변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

관련 정보