Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/10/2011, 15h44   #1
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Par défaut Comparer le contenu de 2 fichiers et récupérer le résultat

Bonjour,

J'ai 2 fichiers texte "pilotes" et "machines" contenant chacun des noms de serveurs (un seul nom par ligne) dont voici respectivement le contenu :

Fichier "pilotes" :

assid01
albidy2
maiss4ips
saytyl2
massy54
......., etc.

Fichier "machines" :

qunr01n
bitric7
assid01
lasmer9
albidy2
zebrai23
albin30
maiss4ips
ertibis08
saytyl2
massy54
.........,etc.

Le fichier "pilotes" est censé être un sous ensemble de du fichier "machines",... mais on a des surprises !
Globalement il s'agit de comparer ligne par ligne le contenu du fichier "pilotes" avec celui du fichier "machines", autrement dit trouver tous les noms qui se trouvent à la fois dans chacun des 2 fichiers.

Mes questions :
1- comment puis-je vérifier qu'il y a pour chaque nom dans "pilotes" le même nom dans "machines"?
2- Puis, si c'est vrai écrire chaque nom trouvé dans un fichier "résultats", et si pour un nom lambda dans "pilotes" on ne trouve pas le même nom dans "machines", on écrit alors une phrase : " le nom : $nom du fichier "pilotes" n'existe pas dans le fichier "machines".

D'avance merci de votre aide
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/10/2011, 16h09   #2
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Ça ne fait exactement ce que tu veux dans la mesure où ça crée 2 fichiers (bon et mauvais), mais ça fait quand même ce que tu demandes :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ cat pilotes 
assid01
albidy2
maiss4ips
saytyl2
massy54
.........,etc.
tttrreee
 
$ cat machines 
qunr01n
bitric7
assid01
lasmer9
albidy2
zebrai23
albin30
maiss4ips
ertibis08
saytyl2
massy54
.........,etc.
 
$ fgrep -f pilotes machines > bon
 
$ fgrep -vf machines pilotes > mauvais
 
$ cat bon 
assid01
albidy2
maiss4ips
saytyl2
massy54
.........,etc.
 
$ cat mauvais 
tttrreee
 
$
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 06/10/2011, 17h41   #3
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Grand Merci. Ca me donne exactement ce que je voulais !
Mais est ce que je peux avoir tous les résultats dans un seul fichier, de telle sorte que le résultat de votre exeple s'affiche comme suit :

Code :
1
2
3
4
5
6
7
$ cat monfichier
assid01
albidy2
maiss4ips
saytyl2
massy54
le nom :  tttrreee du fichier "pilotes" n'existe pas dans le fichier "machines"
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/10/2011, 17h44   #4
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 451
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 451
Points : 2 151
Points : 2 151
Essaye ça (j'ai pas testé) :
Code :
1
2
fgrep -f pilotes machines > resultat
fgrep -vf machines pilotes | sed -re 's/^(.*)$/$1 du fichier "pilotes" n\'existe pas dans le fichier "machines"/' >> resultat
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/10/2011, 18h00   #5
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Citation:
Envoyé par Loceka Voir le message
Essaye ça (j'ai pas testé) :
Code :
1
2
fgrep -f pilotes machines > resultat
fgrep -vf machines pilotes | sed -re 's/^(.*)$/$1 du fichier "pilotes" n\'existe pas dans le fichier "machines"/' >> resultat
La sous-expression n'est pas nécessaire à partir du moment où c'est la ligne entière qui nous intéresse. De plus la référence à une sous expression c'est "\1" et non pas "$1"

Il y a aussi l'apostrophe qui pose problème, même en l'échappant je n'arrive pas à la faire accepter, seule solution sortir de sed, la protéger avec des quotes doubles et revenir dans sed :

Code :
fgrep -vf machines pilotes | sed  's/.*/le nom : "&" du fichier "pilotes" n'"'"'existe pas dans le fichier "machines"/' >> resultat
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/10/2011, 18h03   #6
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Je viens de rencontrer un problème :

Est-ce que le fichier "bon" doit contenir le même nombre de ligne (ou de noms) que dans le fichier "pilotes" ? Dans mon cas, l'équivalent du fichier "bon" contient moins de ligne que "pilotes". D'où cela pourrait-il venir à votre avis ? Rechercher dans l'un ou l'autre des fichier est fastidieux, car ce sont des fichiers trop gros...
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/10/2011, 18h13   #7
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Citation:
Envoyé par bras39 Voir le message
Est-ce que le fichier "bon" doit contenir le même nombre de ligne (ou de noms) que dans le fichier "pilotes" ?
Ben pas forcément, c'est justement le but de ta demande initiale
Je te cite :Le fichier "pilotes" est censé être un sous ensemble de du fichier "machines",... mais on a des surprises !

Citation:
Dans mon cas, l'équivalent du fichier "bon" contient moins de ligne que "pilotes". D'où cela pourrait-il venir à votre avis ?
Normalement tu devrais retrouver les fichiers manquants dans le fichier "mauvais"
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/10/2011, 18h45   #8
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Citation:
Envoyé par zipe31 Voir le message
Normalement tu devrais retrouver les fichiers manquants dans le fichier "mauvais"
C'est ça que je ne comprends pas du tout car un cat du fichier mauvais ne retourne rien ! Et pourtant ne serait-ce en comptant le nombre lignes : j'en ai beaucoup plus dans "pilotes" que dans "bon"...
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 06/10/2011, 18h51   #9
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Dans mon exemple avec les fichiers employés ça marche.

Maintenant sans avoir tous les éléments entre les mains, et notamment les vrais fichiers, je ne sais que te dire
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/10/2011, 07h27   #10
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Citation:
Envoyé par zipe31 Voir le message
Dans mon exemple avec les fichiers employés ça marche.

Maintenant sans avoir tous les éléments entre les mains, et notamment les vrais fichiers, je ne sais que te dire
J'ai compris pourquoi ça ne marchait pas ! En fait "fgrep" est visiblement très sensible à toute sorte d'espace qui précéde ou suive les noms dans un fichier. En l'occurence, il ne prenait pas en compte tous les noms qui sont suivis d'un espace ou d'une tabulation. C'est pourquoi tout les noms suivi d'un espace dans le fichier "pilotes" sont tout simplement ignorés sans toutefois les reporter dans le fichier "mauvais" !
Je déviene que ça doit être également le cas si on avait des espaces ou autres dans le fichier "machines" (je testerai plus tard cette hyptothèse )...

Comment peut-on s'en sortir de cette situation de telle sorte que les mots/noms (ou lignes) suivis ou précédés d'un espace/tabulation dans l'un ou l'autre des 2 fichiers à comparer puissent être pris en compte dans tous les cas ?

D'avance Merci
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/10/2011, 07h40   #11
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Citation:
Envoyé par bras39 Voir le message
J
Comment peut-on s'en sortir de cette situation de telle sorte que les mots/noms (ou lignes) suivis ou précédés d'un espace/tabulation dans l'un ou l'autre des 2 fichiers à comparer puissent être pris en compte dans tous les cas ?

D'avance Merci
Pour enlever les espaces avant et après :
Code :
sed 's/^[ \t]*//;s/[ \t]*$//' fichier_entrée > fichier_sortie
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/10/2011, 21h48   #12
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Citation:
Envoyé par zipe31 Voir le message
Pour enlever les espaces avant et après :
Code :
sed 's/^[ \t]*//;s/[ \t]*$//' fichier_entrée > fichier_sortie
Ca a marché ! Mille mercis...

Deux petites questions au passage :

- Comment dois-je faire pour supprimer du fichier "machines" tous les noms qui figurent dans le fichier "pilotes" et écrire le résultat dans un nouveau fichier ?

- Supposons que mon fichier "pilotes" est composé de 3 colones de noms séparés par soit des tabulations soit par des espaces simples(ou doubles), comment puis-je :
- Supprimer successivement chacune des colones ? ex. : si je supprime la prmière colone, il reste dans mon fichier 2 colones, et ainsi de suite
- Récupérer séparément une seule colone et la mettre dans un autre fichier
- récupérer seulement 2 colones et les copier dans un fichier, etc. jusqu'à la récupération de la 3ème colone...
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2011, 10h12   #13
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 055
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
Localisation : France, Oise (Picardie)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : février 2006
Messages : 3 055
Points : 4 934
Points : 4 934
Citation:
Envoyé par bras39 Voir le message
- Comment dois-je faire pour supprimer du fichier "machines" tous les noms qui figurent dans le fichier "pilotes" et écrire le résultat dans un nouveau fichier ?
Salut
Code bash :
grep -vf pilotes machines >new

Citation:
Envoyé par bras39 Voir le message
- Supposons que mon fichier "pilotes" soit composé de 3 colones de noms séparés par soit des tabulations soit par des espaces simples(ou doubles), comment puis-je :
- Supprimer successivement chacune des colones ? ex. : si je supprime la prmière colone, il reste dans mon fichier 2 colones, et ainsi de suite
Sous Unix, une règle prévaut c'est d'avoir des fichiers toujours bien formatés. Tu as suffisamment d'outils te permettant de bien calibrer tes fichiers. Parce qu'avec "soit des espaces, soit des tabulations" ben c'est pas top. Enfin awk s'en sort malgré tout...
Code bash :
1
2
3
exec 3<pilotes
rm -f pilotes
cat 0<&3 |awk '{print $2 $3}' >pilotes

Citation:
Envoyé par bras39 Voir le message
- Récupérer séparément une seule colone et la mettre dans un autre fichier
Code bash :
awk '{print $x}' pilotes >autre_fichier
(x étant le n° de ta colonne)

Citation:
Envoyé par bras39 Voir le message
- récupérer seulement 2 colones et les copier dans un fichier, etc. jusqu'à la récupération de la 3ème colone...
Ca veut dire quoi "jusqu'à la récupération de la 3° colonne" ???
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2011, 10h25   #14
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Citation:
Envoyé par Sve@r Voir le message
Salut
Code bash :
grep -vf pilotes machines >new
Code :
1
2
3
4
5
fgrep -vf pilote machines >new

ou

grep -F -vf pilotes machines >new
Sans quoi ça ne le fait pas
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 08/10/2011, 12h24   #15
Membre du Club
 
Femme
Inscription : septembre 2011
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Femme

Informations forums :
Inscription : septembre 2011
Messages : 54
Points : 52
Points : 52
Citation:
Envoyé par Sve@r Voir le message
Ca veut dire quoi "jusqu'à la récupération de la 3° colonne" ???
Bonjour,

J'apprécie énormément vos petits commentaires explicatifs, ils me permettent vraiment de comprendre de quoi il s'agit, c'est très pédagogique. Je découvre le shell, je suis désolé d'être neuneu....

Je voudrai aussi dire que mes fichiers proviennent pour beaucoup d'Excel, fichiers texte wordpad et notespad, word, etc, c'est pourquoi...



Par rapport à ta question, je voudrais juste indiquer une progression dans le precessus de suppression et de récupération des colones : à chaque fois que je récupère (pour copier dans un nouveau fichier) ou que je supprime une colone (jusqu'à la suppression ou la récupération de la 3ème colone), les autres lignes restent comme elle est dans mon fichier pilotes.

Je rencontre encore cette situation :
mon fichier pilotes comportent 4 colones séparés par 2 à plusieurs tabulations ou espaces.

Comment faire pour y supprimer les 2 colones du milieu : a) la 4ème colone se décale pour prendre la place de la 2ème; b) elle ne bouge pas de sa position?
bras39 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2011, 12h47   #16
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 055
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
Localisation : France, Oise (Picardie)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : février 2006
Messages : 3 055
Points : 4 934
Points : 4 934
Citation:
Envoyé par bras39 Voir le message
Par rapport à ta question, je voudrais juste indiquer une progression dans le precessus de suppression et de récupération des colones : à chaque fois que je récupère (pour copier dans un nouveau fichier) ou que je supprime une colone (jusqu'à la suppression ou la récupération de la 3ème colone), les autres lignes restent comme elle est dans mon fichier pilotes.
Non. Dans Unix, les traitements sont atomiques (tout ou rien). On part d'un fichier X fini, on lui effectue un traitement T et on obtient un fichier Y fini. Ensuite, on repart du fichier Y, on lui effectue un traitement T' et on obtient un fichier Z et etc etc etc.
Si le fichier Y n'est pas nécessaire, alors on peut combiner les traitements T et T' par des pipes.

Citation:
Envoyé par bras39 Voir le message
Je rencontre encore cette situation :
mon fichier pilotes comportent 4 colones séparés par 2 à plusieurs tabulations ou espaces.

Comment faire pour y supprimer les 2 colones du milieu : a) la 4ème colone se décale pour prendre la place de la 2ème; b) elle ne bouge pas de sa position?
Bon, là il faut aussi arrêter. Sous Unix, il y a distinguo entre "ce qui est" et "ce qui s'affiche". La philosophie est que tu as un fichier de départ. S'il te convient pas alors tu le transformes jusqu'à ce qu'il te convienne. Puis, ensuite, il ne bouge plus et tu ne fais que l'afficher sous différentes formes au travers d'outils. awk est le plus puissant de tous (car il est complètement programmable) mais il y en a d'autres comme cut, tr, pr, etc...
Quand tu dis "supprimer" on comprend "supprimer du fichier d'origine". Mais là, il semblerait que ce soit "supprimer à l'écran" ou plus simplement "afficher d'une certaine façon". Donc là, encore awk
Code bash :
awk '{printf("%s %s\n", $1, $4)}' pilotes
Et si tu as d'autres questions comme "ben en fait je voudrais afficher avec la 2° colonne qui prend la place de la 4° et la 1ère colonne répétée 3 fois" ben là encore awk
Code bash :
awk '{printf("%s %s %s %s %s\n", $1, $1, $1, $3, $2)}' pilotes
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/10/2011, 13h43   #17
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Bonjour,

A supposer que les 2 fichiers soient triés, ceci t'affichera les lignes qui n'existent pas dans un ou l'autre des fichiers (mais pas les lignes identiques). La première colonne étant le nom se trouvant dans le fichier 'machines', la 2nde colonne celui se trouvant dans le fichier 'pilotes'. MANQUANT est affiché pour indiquer que le nom n'existe pas dans le fichier de la colonne.
Code :
join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 machines pilotes
Si tes fichiers ne sont pas triés :
Code :
join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 <(sort machines) <(sort pilotes)
Si ton shell n’accepte pas cette syntaxe, il te suffit de les trier avant

Pour exemple :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cat machines 
qunr01n
bitric7
assid01
lasmer9
albidy2
zebrai23
albin30
maiss4ips
ertibis08
saytyl2
massy54
 
$ cat pilotes                                                                                                                                            
assid01
albidy2
maiss4ips
saytyl2
massy54
oups
 
$ join -i -v1 -v2 -e MANQUANT -j 1 -o 1.1,2.1 <(sort machines) <(sort pilotes)
albin30 MANQUANT
bitric7 MANQUANT
ertibis08 MANQUANT
lasmer9 MANQUANT
MANQUANT oups
qunr01n MANQUANT
zebrai23 MANQUANT
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h02.


 
 
 
 
Partenaires

Hébergement Web