awk deux fichiers basés sur 1ère et 2ème colonne

J’essaie de fusionner un nouveau fichier avec un ancien.

Il y a une clé unique sur la colonne principale, puis un séparateur “=” et une valeur.

  • Si la clé primaire existe dans les deux fichiers, je dois conserver l’ancienne valeur et si la nouvelle est différente, ajoutez un commentaire à proximité de la ligne.
  • Si la clé primaire n’existe que dans l’ancien, conservez-la.
  • Si la clé primaire n’existe que dans la nouvelle, insérez-la

Par exemple:

Dans l’ancien fichier:

$ cat oldfile.txt VAR NAME ONE = FOO TWO BAR = VALUE ; this is a comment 

Dans le nouveau:

 $ cat newfile.txt TWO BAR = VALUE ; this is a comment VAR NAME ONE = BAR NEW = DATA 

Sortie désirée :

 $ cat output.txt VAR NAME ONE = FOO ;new value: ; VAR NAME ONE = BAR TWO BAR = VALUE ; this is a comment NEW = DATA 

J’ai essayé de faire face à diff mais ça ne fonctionne que ligne par ligne, je suis sûr que awk peut le faire .. mais je ne suis pas un expert avec awk. Je peux écrire quelque chose dans ksh pour faire le travail, mais je suis quasiment certain qu’il y a un autre moyen plus rapide et plus simple.

Veuillez noter que l’ordre des lignes dans les fichiers précédents et nouveaux peut changer et que je suis sous AIX (Unix), pas sous Linux.

Merci de votre aide 🙂

MODIFIER:

Je n’ai pas précisé dans le premier post, les nouveaux commentaires doivent être conservés s’ils ne sont pas déjà présents dans le fichier précédent.

Utiliser awk :

 awk ' BEGIN {FS=OFS="="} NR==FNR { line[$1] = $2; next } ($1 in line) && ($2!=line[$1]) { print $0; print ";new value:"; print "; "$1, line[$1]; delete line[$1]; next } ($1 in line) && ($2==line[$1]) { print $0; delete line[$1]; next }1 END { for (k in line) print k, line[k] }' newfile oldfile 

Sortie:

 VAR NAME ONE = FOO ;new value: ; VAR NAME ONE = BAR TWO BAR = VALUE ; this is a comment NEW = DATA 

Solution Perl Tout d’abord, il lit le nouveau fichier dans un hash. Ensuite, il passe sur l’ancien et consulte le hachage pour les modifications. Vous n’avez pas spécifié quoi faire avec les commentaires dans le nouveau fichier, vous devez modifier le code au commentaire correspondant.

 #!/usr/bin/perl use warnings; use ssortingct; my ($oldfile, $newfile) = @ARGV; my %new; my $last; open my $NEW, '<', $newfile or die $!; while (<$NEW>) { chomp; if (/^;/) { $new{$last}{comment} = $_; # What should we do with comments? } elsif (! /=/) { warn "Invalid new line $.\n"; } else { my ($key, $value) = split /\s* = \s*/x, $_, 2; $new{$key}{value} = $value; $last = $key; } } open my $OLD, '<', $oldfile or die $!; while (<$OLD>) { chomp; if (/^;/) { print "$_\n"; } elsif (my ($key, $value) = split /\s* = \s*/x, $_, 2) { if (exists $new{$key}) { print "$key = $value\n"; if ($new{$key}{value} ne $value) { print ";new value:\n"; print "; $key = $new{$key}{value}\n"; } } else { print "$key = $value\n"; } delete $new{$key}; } else { warn "Invalid old line $.\n"; } } for my $key (keys %new) { print "$key = $new{$key}{value}\n"; }