Diff : obtenir uniquement les lignes ajout=c3=a9es

Le
Migrec
Bonjour,

J'ai un fichier CSV avec des identifiants, des mots de passes et
quelques autres données.
J'aimerai extraire les lignes ajoutées au fichier ANCIEN.csv par rapport
au fichier NOUVEAU.csv. Certains lignes ont été modifiées et celles-ci
ne m'intéressent pas. À noter que j'ai une adresse mail dans chaque
ligne qui pourrait servir d'identifiant unique

Comment feriez-vous ?

--
Migrec
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Vincent Lefevre
Le #26444976
On 2017-09-20 16:48:43 +0200, Migrec wrote:
Bonjour,
J'ai un fichier CSV avec des identifiants, des mots de passes et quelques
autres données.
J'aimerai extraire les lignes ajoutées au fichier ANCIEN.csv par rapport au
fichier NOUVEAU.csv. Certains lignes ont été modifiées et celles-ci ne
m'intéressent pas. À noter que j'ai une adresse mail dans chaque ligne qui
pourrait servir d'identifiant unique...
Comment feriez-vous ?

Donc ce que tu veux, ce sont toutes les lignes qui ont un nouvel
identifiant. Je vois deux solutions:
1. Écrire un script dans un langage qui supporte les tableaux
associatifs (e.g. les hash en Perl), et utiliser l'identifiant
comme clé. D'abord, définir les clés existantes en lisant
ANCIEN.csv; dans un second temps, lire NOUVEAU.csv et tester
pour chaque ligne si la clé est déjà utilisée.
2. Avec un script shell utilisant grep -f. Dans un premier temps, en
lisant ANCIEN.csv, stocker la liste des identifiants à rejeter dans
un fichier FILE. Dans un second temps, un truc du style:
grep -v -f FILE NOUVEAU.csv
(pas testé). Dans la liste de rejet, il faut faire attention sur
les regexp, au cas une adresse mail peut avoir des caractères
spéciaux, si une adresse mail peut être une sous-chaîne d'une
autre, ou si elle peut apparaître ailleurs dans la ligne (i.e.
pas comme identifiant). Bref, la solution (1) me semble plus
simple.
--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Yves Rutschle
Le #26444977
On Wed, Sep 20, 2017 at 04:48:43PM +0200, Migrec wrote:
J'ai un fichier CSV avec des identifiants, des mots de passes et quelques
autres données.

C'est mal, il faut hacher les mots de passe.
J'aimerai extraire les lignes ajoutées au fichier ANCIEN.csv par rapport au
fichier NOUVEAU.csv. Certains lignes ont été modifiées et celles-ci ne
m'intéressent pas. À noter que j'ai une adresse mail dans chaque ligne qui
pourrait servir d'identifiant unique...

En Perl, avec un tableau associatif indexé par adresse mail,
par ex. avec des fichiers:
toto:tata::0:2
# Lire et indexer le premier fichier
my %lines;
foreach (<$file1>) {
my ($f1, $f2, $email, $f3, $f4) = split /:/;
$lines{$email} = 1;
}
# Imprimer ce qui n'est pas dans le premier fichier
foreach (<$file2>) {
my ($f1, $f2, $email, $f3, $f4) = split /:/;
print unless exists $lines{$email};
}
Pas testé!
Y.
Erwan David
Le #26444988
Le 09/20/17 à 17:25, Yves Rutschle a écrit :
On Wed, Sep 20, 2017 at 04:48:43PM +0200, Migrec wrote:
J'ai un fichier CSV avec des identifiants, des mots de passes et quelques
autres données.

C'est mal, il faut hacher les mots de passe.

ET les saler avant, contrairement au steak.
Migrec
Le #26445000
Le 20/09/2017 17:25, Yves Rutschle a écrit :
On Wed, Sep 20, 2017 at 04:48:43PM +0200, Migrec wrote:
J'ai un fichier CSV avec des identifiants, des mots de passes et quelques
autres données.

C'est mal, il faut hacher les mots de passe.

Malheureusement, ce n'est pas moi qui produit le fichier...
J'aimerai extraire les lignes ajoutées au fichier ANCIEN.csv par rapport au
fichier NOUVEAU.csv. Certains lignes ont été modifiées et celles-ci ne
m'intéressent pas. À noter que j'ai une adresse mail dans chaque ligne qui
pourrait servir d'identifiant unique...

En Perl, avec un tableau associatif indexé par adresse mail,
par ex. avec des fichiers:
toto:tata::0:2
# Lire et indexer le premier fichier
my %lines;
foreach (<$file1>) {
my ($f1, $f2, $email, $f3, $f4) = split /:/;
$lines{$email} = 1;
}
# Imprimer ce qui n'est pas dans le premier fichier
foreach (<$file2>) {
my ($f1, $f2, $email, $f3, $f4) = split /:/;
print unless exists $lines{$email};
}


Je ne connais pas du tout le perl (et du coup pas tout compris...) mais
j'ai réussi à bricoler un peu pour avoir un résultat qui me parait
satisfaisant.
Merci beaucoup.
Le script :
#!/usr/bin/perl -w
my $file1 = $ARGV[0];
my $file2 = $ARGV[1];
open(my $old, '<', $file1) or die "Can't open $file1: $!";
open(my $new, '<', $file2) or die "Can't open $file2: $!";
# Lire et indexer le premier fichier
my %lines;
foreach (<$old>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
$lines{$email} = 1;
}
# Imprimer ce qui n'est pas dans le premier fichier
foreach (<$new>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
print unless exists $lines{$email};
}
Migrec
Le #26448876
Le 20/09/2017 à 20:43, Migrec a écrit :
Je ne connais pas du tout le perl (et du coup pas tout compris...)
mais j'ai réussi à bricoler un peu pour avoir un résultat qui me
parait satisfaisant.
Merci beaucoup.
Le script :
#!/usr/bin/perl -w
my $file1 = $ARGV[0];
my $file2 = $ARGV[1];
open(my $old, '<', $file1) or die "Can't open $file1: $!";
open(my $new, '<', $file2) or die "Can't open $file2: $!";
# Lire et indexer le premier fichier
my %lines;
foreach (<$old>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
$lines{$email} = 1;
}
# Imprimer ce qui n'est pas dans le premier fichier
foreach (<$new>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
print unless exists $lines{$email};
}

Bonjour,
Je déterre ce fil de discussion car l'interface qui produit mon fichier
en entrée a changé. Grr.
Je me retrouve avec un fichier issu de DOS (donc des fins de lignes avec
^M$). Jusque là tout va bien mais désormais, j'ai également un caractère
$ dans l'un des champs (c'est un champ de type adresse qui peut contenir
4 lignes donc 3 $ potentiellement).
Option 1
Je traite uniquement les lignes qui commencent par ". Je contourne le
problème. Comment puis-je faire cela ?
Option 2
J'indique à Perl qu'il s'agit de la même ligne lorsqu'il y a un $. Mais
comment ?
--
Migrec
Dominique Dumont
Le #26448884
On Tuesday, 24 October 2017 14:52:55 CEST Migrec wrote:
e me retrouve avec un fichier issu de DOS (donc des fins de lignes avec
^M$). Jusque là tout va bien mais désormais, j'ai égalemen t un caractère
$ dans l'un des champs (c'est un champ de type adresse qui peut contenir
4 lignes donc 3 $ potentiellement).
Option 1
Je traite uniquement les lignes qui commencent par ". Je contourne le
problème. Comment puis-je faire cela ?
Option 2
J'indique à Perl qu'il s'agit de la même ligne lorsqu'il y a un $. Mais
comment ?

Pas sur de comprendre. Perl devrait traiter les '$' venant du fichier d'ent rée
comme un autre caractère Bref ton script devrait fonctionner.
Si ce n'est pas le cas, il va nous falloir plus de détails (script et un
exemple d'entrée).
HTH
--
https://github.com/dod38fr/ -o- http://search.cpan.org/~ddumont/
http://ddumont.wordpress.com/ -o- irc: dod at irc.debian.org
Migrec
Le #26448889
Le 24/10/2017 à 15:43, Dominique Dumont a écrit :
On Tuesday, 24 October 2017 14:52:55 CEST Migrec wrote:
e me retrouve avec un fichier issu de DOS (donc des fins de lignes avec
^M$). Jusque là tout va bien mais désormais, j'ai également un caractère
$ dans l'un des champs (c'est un champ de type adresse qui peut contenir
4 lignes donc 3 $ potentiellement).
Option 1
Je traite uniquement les lignes qui commencent par ". Je contourne le
problème. Comment puis-je faire cela ?
Option 2
J'indique à Perl qu'il s'agit de la même ligne lorsqu'il y a un $. Mais
comment ?

Pas sur de comprendre. Perl devrait traiter les '$' venant du fichier d'entrée
comme un autre caractère Bref ton script devrait fonctionner.
Si ce n'est pas le cas, il va nous falloir plus de détails (script et un
exemple d'entrée).

Oui effectivement il fonctionne ce script perl... mea culpa.
C'est simplement le fichier initial (pas de retour chariot à l'intérieur
des lignes) qui diffère du fichier actuel (retours chariot dans les lignes).
--
Migrec
Marc Chantreux
Le #26448903
Oui effectivement il fonctionne ce script perl... mea culpa.
C'est simplement le fichier initial (pas de retour chariot à
l'intérieur des lignes) qui diffère du fichier actuel (retours
chariot dans les lignes).

hello,
il y a pas mal d'amélioration possibles pour rendre ton script
un peu plus facile a maintenir mais voilà celle qui me parait la plus
intéressante
tu écris
my %lines;
foreach (<$old>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
$lines{$email} = 1;
}
hors seul le champ $email t'intéresse alors ne garde que celui-ci
my %lines;
foreach (<$old>) {
my $email = (split /;/)[3];
$lines{$email} = 1;
}
et là on se rend compte que lines ne contient pas des lignes
mais une paire pour chaque ligne avec une adresse email en clef et
1 comme valeur unique ( $email => 1 ). du coup on peut écrire
my %found_email = map { (split /;/)[3] => 1 } <$old>;
de meme on filtrera ton 2eme fichier presque de la meme manière
map {print if $found_email{ (split /;/)[3] } <$new>;
marc
Migrec
Le #26448950
Le 24/10/2017 à 17:31, Marc Chantreux a écrit :
Oui effectivement il fonctionne ce script perl... mea culpa.
C'est simplement le fichier initial (pas de retour chariot à
l'intérieur des lignes) qui diffère du fichier actuel (retours
chariot dans les lignes).

hello,
il y a pas mal d'amélioration possibles pour rendre ton script
un peu plus facile a maintenir mais voilà celle qui me parait la plus
intéressante
tu écris
my %lines;
foreach (<$old>) {
my ($f1, $f2, $f3, $email, $f4, $f5, $f6, $f7,$f8) = split /;/;
$lines{$email} = 1;
}
hors seul le champ $email t'intéresse alors ne garde que celui-ci
my %lines;
foreach (<$old>) {
my $email = (split /;/)[3];
$lines{$email} = 1;
}
et là on se rend compte que lines ne contient pas des lignes
mais une paire pour chaque ligne avec une adresse email en clef et
1 comme valeur unique ( $email => 1 ). du coup on peut écrire
my %found_email = map { (split /;/)[3] => 1 } <$old>;
de meme on filtrera ton 2eme fichier presque de la meme manière
map {print if $found_email{ (split /;/)[3] } <$new>;

Effectivement, c'est bien plus simple ainsi. Malheureusement, je n'y
connais rien en perl... J'ai juste mis une négation (not)= après le
dernier if afin de garder que les lignes différentes.
Mais quoique je fasse, la sortie inclut toute de même les lignes faisait
suite à un retour chariot... Solution temporaire : supprimer la colonne
Adresse avec un tableur et passer le script.
--
Migrec
Dominique Dumont
Le #26448988
On Tuesday, 24 October 2017 21:46:28 CEST Migrec wrote:
Mais quoique je fasse, la sortie inclut toute de même les lignes fai sait
suite à un retour chariot... Solution temporaire : supprimer la colo nne
Adresse avec un tableur et passer le script.

Je ne comprends toujours pas le problème. Envoie un exemple si tu veu x qu'on
t'aide plus. Sinon on perd trop de temps.
--
https://github.com/dod38fr/ -o- http://search.cpan.org/~ddumont/
http://ddumont.wordpress.com/ -o- irc: dod at irc.debian.org
Publicité
Poster une réponse
Anonyme