Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 04/02/2015, à 12:00

Linuxman[13]

[Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Bonjour, je viens de débuter en BASH et j'ai un problème à résoudre à l'aide d'un script.
Je dois comparer 2 fichiers contenant la file d'attente d'un même serveur de mail et je dois retourner les mails qui ne sont pas partis.
J'ai le raisonnement suivant : je lis le premier fichier ligne par ligne, et je compare chacune de ces lignes aux deuxième fichier afin de voir si il en existe deux identiques.
J'ai écris ce code mais seule la première ligne, qui est communes aux 2 fichiers, est sauvegardée :

while read line < $fichier1
do
    read enil < $fichier2
    if [ "$enil" = "$line" ]
    then
        echo $line > same.txt   
    fi
done

Dernière modification par Linuxman[13] (Le 10/02/2015, à 16:33)

Hors ligne

#2 Le 04/02/2015, à 12:19

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Bof bof...

Plus efficace d'utiliser un sort sur les 2 fichiers puis de passer la commande qui gagne à être connue; à savoir : comm

Hors ligne

#3 Le 04/02/2015, à 12:27

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

D'accord merci beaucoup pour l'info'. Petite question, le "sort" sert-il uniquement à organiser les lignes d'un fichier où il permet dans sélectionner certaine et de "supprimer" les autres ?

Hors ligne

#4 Le 04/02/2015, à 12:42

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Le sort comme le man donné dans ma réponse l'indique ;-), sert à trier un fichier et accessoirement à en supprimer certaines avec l'option -u (pour uniq) et le comm comme le man donné dans ma réponse l'indique ;-), sert à extraire et supprimer les lignes répondant aux critères...

Hors ligne

#5 Le 04/02/2015, à 13:09

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Merci ! Du coup j'ai ce script :
#!/bin/sh
fichier1=/home/pedro/Bureau/Pierre/pq1.txt
fichier2=/home/pedro/Bureau/Pierre/pq2.txt

sort $fichier1 > tri1.txt
sort $fichier2 > tri2.txt

comm -12  tri1.txt tri2.txt > comparaison.txt

..qui renvoie dans le fichier "comparaison.txt" les lignes communes au fichier tri1.txt et tri2.txt
ça ne me semble pas très propre mais ça à l'air de fonctionner, qu'en penses-tu ?

Hors ligne

#6 Le 04/02/2015, à 14:02

HP

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires


cat /dev/urandom >/dev/null 2>&1 #github

Hors ligne

#7 Le 04/02/2015, à 15:25

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Linuxman 13 a écrit :

...ça ne me semble pas très propre mais ça à l'air de fonctionner, qu'en penses-tu ?

Ben si c'est relativement propre (2 petites choses néanmoins ;-)
1 - Les fichiers temporaires de travail comme 'tri1.txt' et 'tri2.txt' peuvent avantageusement être créés sous /tmp. Comme cela, pas de pollution avec des résultats intermédiaires ni de travail de suppressions pouvant devenir fastidieux.
2 - Ajout de la directive 'set -o errexit' très utile dans l'enchaînement de scripts.

#!/bin/sh
set -o errexit
...
comm -12 tri1.txt tri2.txt > comparaison.txt

Là, je dois dire que je ne connaissais pas et qui est la solution la plus compacte.

Hors ligne

#8 Le 04/02/2015, à 16:52

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Merci pour la réponse mais je ne comprends pas vraiment le rôle de "set -o errexit".
Avec la commande d'HP j'arrive presque au résultat voulu grâce à ce script.
#!/bin/sh
grep -F -x -f pq1.txt pq2.txt>/tmp/grep.txt
cut -d' ' -f1,10,42 /tmp/grep.txt >/tmp/cut.txt
grep [^-a-zA-Z0_9] /tmp/cut.txt > /tmp/tri.txt

J'ai à la fin un fichier (le tri.txt) qui ressemble à ça :

0D3B117014F xxxx@xxxx.org   ####ID du mail + émetteur

  azer@ty.com                           ###Destinataire
5605117015B cc.xpol@xxx.org   ####ID du mail + émetteur

  ploefze@fsdfaf.fr                  ###Destinataire
                       
Cependant ce n'est pas très lisible, il faudrait que j'arrive à mettre tous les élements concernant un mail, sur la même ligne ! :s

Hors ligne

#9 Le 04/02/2015, à 18:29

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Linuxman a écrit :

... il faudrait que j'arrive à mettre tous les élements concernant un mail, sur la même ligne ! :s

Ce que je comprends comme joindre 2 lignes consécutives du fichier /tmp/tri.txt.
Si le cas, la commande paste devrait répondre au problème...

$ cat /tmp/tri.txt | paste - - 

Si pas le cas, un exemple pour bien comprendre la demande.

Hors ligne

#10 Le 05/02/2015, à 10:17

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Oui je crois que c'est ce qu'il me fallait mais j'arrive au résultat voulu (toutes les informations sur la même ligne) en mettant 3 "-". Mais pourrais-tu m'expliquer le rôle de ces "-" ? Je ne le vois nulle part sur le man ..

Hors ligne

#11 Le 05/02/2015, à 11:22

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Linuxman 13 a écrit :

... j'arrive au résultat voulu (toutes les informations sur la même ligne) en mettant 3 "-".

Car il y a une ligne vide entre les 2 lignes à regrouper et donc cela fait 3 lignes à joindre :

0D3B117014F xxxx@xxxx.org   ####ID du mail + émetteur

  azer@ty.com                           ###Destinataire
Linuxman 13 a écrit :

... Mais pourrais-tu m'expliquer le rôle de ces "-" ? Je ne le vois nulle part sur le man.

Ben si, je lis dans le man de paste : "Si aucun fichier n'est indiqué, ou si le nom `-' est mentionné, la lecture se fait sur l'entrée standard.".
Maintenant, cf. 10 examples of paste command usage in Linux en guise d'explications...

Hors ligne

#12 Le 05/02/2015, à 13:04

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

D'accord. Oui j'ai aussi lu cette ligne mais je ne comprends pas son sens.
L'entrée standard représente le clavier n'est-ce pas ?
Donc "Si aucun fichier n'est indiqué, ou si le nom '-' est mentionné, la lecture se fait sur [le clavier]" ? Je ne comprends pas le sens de la commande au final .. sad

Hors ligne

#13 Le 05/02/2015, à 15:10

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Linuxman 13 a écrit :

L'entrée standard représente le clavier n'est-ce pas ?

Oui mais le pipe ('|') permet de brancher la sortie (*) de la commande cat sur l'entrée de la commande paste.
cf. 1.5 Commandes de bases [d'Unix] - § 1.5.1.3 Pipes

(*) Attention, il y a 2 sorties : La sortie standard (&1) et la sortie erreur (&2).

Si bien que les 4 lignes suivantes

grep -F -x -f pq1.txt pq2.txt >/tmp/grep.txt
cut -d' ' -f1,10,42 /tmp/grep.txt >/tmp/cut.txt
grep [^-a-zA-Z0_9] /tmp/cut.txt > /tmp/tri.txt
cat /tmp/tri.txt | paste - - -

peuvent avantageusement être écrites en une seule ce qui évite la création d'une multitude de fichiers intermédiaires et qui est par la même plus rapide.

grep -F -x -f pq1.txt pq2.txt | cut -d' ' -f1,10,42 | grep [^-a-zA-Z0_9] | paste - - -

Hors ligne

#14 Le 05/02/2015, à 17:05

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Merci beaucoup pour tes explications. Je connaissais un peu le principe du pipe.
Ton écriture est en effet bien plus simplifier et évite la création de 2 fichiers sur 3. Je vais l'adopter !
Enfin, pourrais-tu m'aiguiller ? Je cherche à faire une mise en forme du fichier "tri.txt", en effet ce dernier ressemble à cela maintenant :
        -----ID----  --------Date------                 -----Emmetteur-----                    -----Destinataire-----
        0D3B117014F Thu Jan 29 11:25:03 x.mrxx@domaine.org                   test@arobase.com
        5605117015B Thu Jan 29 13:03:20 x.mmexx@domaine.org                  voila@bash.fr
Je souhaiterais pouvoir mieux l'organiser (afin que les colonnes soit alignées et que le document commence à la colonne zéro)
Connaîtrais-tu un outil efficace ?

Hors ligne

#15 Le 05/02/2015, à 17:56

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Il y a column (cf. man column) qui donne sur les 2 lignes :

        0D3B117014F Thu Jan 29 11:25:03 x.mrxx@domaine.org                   test@arobase.com
        5605117015B Thu Jan 29 13:03:20 x.mmexx@domaine.org                      voila@bash.fr

le résultat suivant :

$ cat <file> | column -t
0D3B117014F  Thu  Jan  29  11:25:03  x.mrxx@domaine.org   test@arobase.com
5605117015B  Thu  Jan  29  13:03:20  x.mmexx@domaine.org  voila@bash.fr

Hors ligne

#16 Le 06/02/2015, à 09:40

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Merci pour ta réponse, lorsque j'ajoute le "column -t" à ma commande grâce à un "|" je me retrouve avec le résultat, je n'ai plus qu'eu à modifier l'en-tête afin que cela corresponde avec les colonnes et je me retrouve avec le résultat voulu :
-------ID--------  -----------Date-----------  ------Emetteur-------       --------Destinataire--------
0D3B117014F  Thu  Jan  29  11:25:03   mr.xxx@xxx.org           siteservices.eu@pddi.com
5605127015Z  Mon  Feb  04  15:00:00  pedrox@isc84.org       capingpas@gmail.com

(J'ai du un peu modifier ici parce que cela ne s'affichait pas correctement après mon copié | collé)

Dernière modification par Linuxman[13] (Le 06/02/2015, à 09:50)

Hors ligne

#17 Le 06/02/2015, à 11:21

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

C'est effectivement une solution mais en toute rigueur, l'entête ajoutée en début de fichier et qui va être traitée par column doit avoir le même nombre de colonnes quitte à refaire une petite substitution.

1) Fichier avec entête avant traitement par column (les champs de la colonne 'Date' sont définis comme 'JJJ MMM JJ HH:MM:SS')

-------ID-------- JJJ MMM JJ HH:MM:SS ------Emetteur-------  --------Destinataire--------
        0D3B117014F Thu Jan 29 11:25:03 x.mrxx@domaine.org                   test@arobase.com
        5605117015B Thu Jan 29 13:03:20 x.mmexx@domaine.org                      voila@bash.fr

2) Après traitement par column

-------ID--------  JJJ  MMM  JJ  HH:MM:SS  ------Emetteur-------  --------Destinataire--------
0D3B117014F        Thu  Jan  29  11:25:03  x.mrxx@domaine.org     test@arobase.com
5605117015B        Thu  Jan  29  13:03:20  x.mmexx@domaine.org    voila@bash.fr

3) Rétabissement de la colonne 'Date' comme tu le souhaites avec un sed

$ cat <file> |  column -t | sed 's/JJJ  MMM  JJ  HH:MM:SS/---------Date---------/'
-------ID--------  ---------Date---------  ------Emetteur-------  --------Destinataire--------
0D3B117014F        Thu  Jan  29  11:25:03  x.mrxx@domaine.org     test@arobase.com
5605117015B        Thu  Jan  29  13:03:20  x.mmexx@domaine.org    voila@bash.fr

Dernière modification par claudius01 (Le 07/02/2015, à 17:12)

Hors ligne

#18 Le 09/02/2015, à 11:41

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Ok, merci beaucoup pour le tuyau ! C'est bien plus ordonné !

Hors ligne

#19 Le 09/02/2015, à 15:26

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Je reviens poster un message, j'espère que tu le verras. J'ai rencontré des problèmes avec mon script.
Je crois que cela vient du "cat fichier.txt | column -t > fichier.txt
Je crois que column n'aime pas trop le fait de traiter le contenu d'un fichier pour le réenregistrer dedans. En effet, un problème persiste. Lors de l'exécution du script, parfois le fichier "fichier.txt" a du contenu, et à d'autre moment non (alors qu'il s'agit toujours des mêmes fichiers traités, je compare "pq1.txt" avec "pq2.txt" et j'envoie le résultat dans "fichier.txt").
Là j'ai envoyé le résultat dans un fichier ayant un autre nom et ça à l'air de fonctionner systématiquement (mais du coup, j'ai 2 fichier dans /tmp au lieu d'un, mais ce n'est pas grave ..)

Hors ligne

#20 Le 09/02/2015, à 16:18

LeoMajor

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Je dois comparer 2 fichiers contenant la file d'attente d'un même serveur de mail et je dois retourner les mails qui ne sont pas partis.

Enfin, je suppose que c'est juste pour t'amuser en bash, sinon question messagerie, j'aurais fait le contraire avec pflogsumm, pour retourner les messages réellement partis.
A vrai dire, faire un test sur mailq, est beaucoup plus casse gueule, pour dénombrer les messages, qui ne partent pas.

Hors ligne

#21 Le 09/02/2015, à 17:09

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Non non haha tongue Je suis en stage, on m'a demandé de récupérer ces informations dans un fichier afin d'intégrer une nouvelle fonctionnalité à Zabbix. A quoi sert de savoir quels sont les messages réellement partis si l'on n'a pas ceux qui bouchonnent ? Ce sont eux qui posent problèmes non ?

Hors ligne

#22 Le 09/02/2015, à 17:40

claudius01

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

Linuxman 13 a écrit :

... Je crois que column n'aime pas trop le fait de traiter le contenu d'un fichier pour le réenregistrer dedans.

D'une manière générale, rediriger un flux d'entrée vers une commande que réécrit dans ce même flux d'entrée est tout simplement non garanti et je ne le fais jamais ;-)

Hors ligne

#23 Le 10/02/2015, à 11:02

Linuxman[13]

Re : [Résolu!] BASH : Comparer 2 fichiers et relever les lignes similaires

D'accord, merci, je le saurais .. smile

Hors ligne