Bonjour,
Je parses un email (format eml) en Bash.
Voici un exemple du contenu :
root@mta:~/stage# cat test.eml
Date: Wed, 27 Apr 2011 09:58:01 +0200 (CEST)
From: Dupond <dupond@reseau.loc>
To: admin@reseau.loc
Subject: test
Message-ID: <9fc22f81-5d3c-4c06-8237-e2c2f9f947c3@mta>
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-Originating-IP: [192.168.2.57]
X-Mailer: Zimbra 7.0.1_GA_3105 (ZimbraWebClient - FF3.0 (Linux)/7.0.1_GA_3105)
Bonjour,
Je me permets de vous faire remarquer ce test de contenu d'Email. Là, c'est le contenu de mon email.
Pour récupérer les champs importants, j'ai fait un : cat test.eml | grep -e "To" -e "From" -e "Subject" -e "Date"
En revanche, j'aimerais maintenant ne récupérer que le contenu du mail, c'est à dire de "Bonjour," à "contenu de mon email.".
Je vois pas comment faire =/.
Un petit coup de main ?
Bonne journée
# Python + email
Posté par koopa . Évalué à 4.
En bash, c'est assez difficile de traiter des emails.
Moi j'utilise plutôt python et le paquetage email.
[^] # Re: Python + email
Posté par MarbolanGos (site web personnel) . Évalué à -1.
Mince j'ai été grillé de quelques secondes...
[^] # Re: Python + email
Posté par Michaël (site web personnel) . Évalué à 4.
Tout dépend de ce que tu veux faire: récupérer le corps de l'EMail n'est quand même pas si compliqué qu'il faille jeter son script shell pour transformer son programme en script Python.
On tire au maximum parti de l'architecture d'UNIX lorsqu'on utilise le shell pour coordonner les traitements: presque tous les langages on un accès au shell, et on obtient une réutalisabilité de tous ces efforts.
Pour la question de récuperer le corps, tu peux définir la fonction
et l'utiliser comme suit
Attention aux useless use of cat: au lieu de faire cat & pipe il vaut mieux utiliser un opérateur de redirection (les chevrons), comme dans
ou l'exemple précédent.
# Parser en python ?
Posté par MarbolanGos (site web personnel) . Évalué à 3.
Bonjour,
il existe déjà des classes toutes faites pour le faire en python : http://docs.python.org/library/email.parser.html
En bash sinon, si l'entête est de taille fixe, un coup de tail et/ou de head devrait suffire non ?
# sed ?
Posté par Kerro . Évalué à 3.
[^] # Re: sed ?
Posté par Jeoffrey . Évalué à 1.
Arf, cela ne me renvoie strictement rien :S.
[^] # Re: sed ?
Posté par Michaël (site web personnel) . Évalué à 2.
Remplace l'expression rationnelle
^$
par^\r$
mais la séquence\r
ne marche pas avec tous les sed.[^] # Re: sed ?
Posté par defmonkey . Évalué à 1.
Et donc tu rentres directement le caractère ^M. Dans un xterm, c'est avec la séquence
'C^v Enter'
. Ça c'est compris par tous les sed.[^] # Re: sed ?
Posté par JJD . Évalué à 4.
En fait l'idée est bonne. L'en-tête d'un mail n'est pas de taille fixe.
En revanche, l'en-tête et le corps du mail sont séparés par une ligne vide. La commande sed indiquée devrait donc fonctionner…
Le seul soucis est que dans un mail, les changement de lignes sont indiqués par des CR-LF, alors que sous Unix on utilise le LF seul. La ligne de séparation n'est donc pas considérée comme une ligne vide mais comme une ligne contenant le CR.
Pour que cela fonctionne, il suffit de modifier la commande ainsi :
ou, si on veut prendre en compte aussi bien les fins de lignes CR-LF que LF
[^] # Re: sed ?
Posté par Kerro . Évalué à 2.
Bien vu. Je n'ai pas vérifié avec un véritable email.
Ta seconde syntaxe passe tout, ça couvre les besoins exotiques.
[^] # Re: sed ?
Posté par Michaël (site web personnel) . Évalué à 1.
Ton script veut dire: sélectionne les lignes comprises entre une ligne vide (adresse
/^$/
)et la suivante ( adresse+1
) et affiche les (opérationp
). Ce n'est pas du tout ce que veut l'OP. Tu l'as testé?[^] # Re: sed ?
Posté par netsurfeur . Évalué à 3.
extrait le corps du mail.
# Pas de python
Posté par Jeoffrey . Évalué à 1.
Non, Python n'est pas envisageable, tout mon script est fait en Bash, un portage en python me prendrais trop de temps =/.
Normalement oui, le début est fixe... Donc si je supprimes X lignes, ça peut marcher...
Mais dans le cas où c'est aléatoire ?
J'ai tenté un grep "nn", mais il ne me renvoie rien.
# Tentative
Posté par DLFP est mort . Évalué à 3.
Je pense comme les autres qu'il vaut mieux utiliser la librairie de Python pour le faire.
Cependant : déjà tu devrais faire grep -e '^To: ' plutôt que grep -e "To:", sinon tu pourrais récupérer des lignes qui ne sont pas du tout un header.
Et tu devrais séparer le contenu avant de faire le grep des headers. Ils sont séparés de manière très simple : c'est la première ligne vide. Donc quelque chose comme… grep -m1 -n -e '^$' pour obtenir le numéro de cette ligne vide, et ensuite tu peux tail/head.
DLFP >> PCInpact > Numerama >> LinuxFr.org
[^] # Re: Tentative
Posté par Michaël (site web personnel) . Évalué à 2.
Le couple
grep & tail & head
est une bonne idée. Pour rester avecawk
, utilisé dans mon exemple de solution pour récupérer le corps, l'isolation du header se fait comme cela:# en shell
Posté par defmonkey . Évalué à 1.
cat test.eml | sed -n -e '/^^M*$/,$ p'
Attention, le
^M
est bien leCR
, ie le caractère de code ascii 0x0D. Dans un xterm+bash, c'est'C^v Enter'
, avec emacs c'est'C^q Enter'
, avec les autres je ne sais pas.[^] # Re: en shell
Posté par Michaël (site web personnel) . Évalué à 1.
Cette solution marche, mais elle a le petit défaut de montrer la ligne vide, qu'on peut cacher avec
tail
.Encore un useless use of cat ™ :)
[^] # Re: en shell
Posté par defmonkey . Évalué à 1.
ok:
[...] | tail -n +2
Mais on arrive dans le cosmétique, quand même ;)
[^] # Re: en shell
Posté par Michaël (site web personnel) . Évalué à 1.
Ce n'est pas cosmétique: le but de la manip est de récupérer le corps du message.
# en bash
Posté par NBaH . Évalué à 2.
...
?
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.