Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

#1 Le 18/11/2013, à 01:20

Spirale21

sed et références arrières

Bonjour
je viens vers vous car je n'y comprends rien.. voilà je veux faire du publipostage avec latex donc j'écris des modèles de lettres avec des champs qui peuvent changer et pour les reconnaître je les entoure de !. Exemple:

 Il fait beau aujourd'hui !ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit! 

un truc du style... oui je m'amuse des fois
bref comme c'est du publipostage je veux remplacer les champs entourés de ! par la source. Pour cette substitution je fais

sed -i s/!\(.*\)!/\1/g $1

Alors $1 sera le nom du fichier et donc j'agirais directement sur lui d’où l'option -i
mais voilà ce que ça me donne

 Il fait beau aujourd'hui !ville, je suis sous le temps! et parent profite pleinement de endroit 

et je ne comprends pas pourquoi
et si je mets :

sed -i s/!\(\.*\)!/\1/g $1

j'obtiens

 Il fait beau aujourd'hui !ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit! 

j'avoue je ne comprends pas ça viendrait de mon expression régulière? parce que

sed -i s/!.*!/totor/g $1

Résultat:

 Il fait beau aujourd'hui totor, je suis sous le totor et totor profite pleinement de totor 

Merci de m'éclairer
PS: j'ai mis le flag g car mon fichier fait environ 20 lignes et !ville! de retrouve un peu partout wink


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#2 Le 18/11/2013, à 07:54

gigiair

Re : sed et références arrières

Ben oui, ça vient de ton ER.
Je mettrais

sed -i s/!\([^!]*\)!/\1/g $1

Les spécialistes (dont je ne suis pas) t'expliqueront pourquoi ta solution ne marche pas, mais pour faire du publipostage en LaTeX, pourquoi n'utilises-tu pas plutôt le package datatool ?


--
JJR.

Hors ligne

#3 Le 18/11/2013, à 11:07

Spirale21

Re : sed et références arrières

ça marche ton sed!! mais je sais pas non plus pourquoi donc j'espère qu'on va m'expliquer cette expression rationnelle sinon un grand merci.
Pour le package datatool de latex soyons honnête..je connaissais pas (pas beaucoup de recherches avant je l'avoue sur le publipostage avec latex). Ensuite il a l'air trop strict dans le sens ou j'utilise l'environnement lettre et 2 lettres types et un modèle personnalisé au format .txt . Je voulais m'essayer au bash en général parce que j'apprends (cours, tuto) mais j'ai jamais d'idée d'un script pour me rendre service (manque d'imagination ???) et le publipostage sur latex m'a donné une raison de faire un script qui me saura utile (et je trouve ça plus marrant de faire un truc à toi que d'utiliser un truc fait par les autres si tu peux le faire (=avoir les compétences pour)).


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#4 Le 18/11/2013, à 11:23

gigiair

Re : sed et références arrières

[^!]* permet de sauter toue suite de caractères qui ne sont pas !.
Donc !\([^!]*\)! capture tout ce qui se trouve strictement entre deux ! consécutifs.

Pour ma part, j'utilise la classe scrlttr2 qui est plus souple que la classe lettre.
Voici mon exemple de publipostage

%% Author: gigiair@forum.ubuntu-fr
%% Version: $Id: publipost.tex,v 0.0 2012/12/13 08:56:26 ubntjjr Exp$
%% Ficher exemple de publipostage, utilisant datatool et scrlttr2

\documentclass[paper=a4,fontsize=12pt,french]{scrlttr2}
\usepackage[T1]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage{kpfonts}
\usepackage{geometry}
\geometry{verbose,a4paper,lmargin=3cm,rmargin=3cm}
\usepackage{graphicx}
\usepackage{setspace}
\usepackage{numprint}
\nprounddigits{2}

\usepackage[math=fp]{datatool}
\usepackage[frenchb]{babel}


\setlength\parskip{\medskipamount}
\setlength\parindent{0pt}

\setstretch{1.15}

%% Load an *.lco style file (see KOMA documentation)
\LoadLetterOption{NF}%


%% THE CLASS OPTIONS
%% Remove preceeding '%' to uncomment an item
\KOMAoptions{%
% Ne pas oublier de retirer (resp remettre) la virgule de la première option.
%,headsepline=true%            separate the header with a line on page >1
%,footsepline=true%             separate the footer	 with a line on page >1
%pagenumber=botcenter%   position of the page number (see docu)
%,parskip=false%          Use indent instead of skip (more options cf. docu)
fromalign=left%        alignment of the address
%,fromrule=aftername%    separate the address with a line?
,fromphone=true%         print sender phone number
%,fromfax=true%          print sender fax number
,fromemail=true%           print sender e-mail address
%,fromurl=true%               print sender URL
%,fromlogo=true%         print a logo (position depends on fromalign)
%,addrfield=false%        print an address field?
%,backaddress=false%  print the back address?
%,subject=afteropening,titled% alternative subject layout and position
%,locfield=narrow%      width of the (extra) location field
%,foldmarks=false%      print foldmarks?
%,numericaldate=true%  date layout
%,refline=wide%             layout of the refline
}

%% Customize Separators
%%\setkomavar{placeseparator}{ -- }
\setkomavar{backaddressseparator}{ $\cdot$ }
\setkomavar{emailseparator}{~:~}
\setkomavar{enclseparator}{ > }
%\setkomavar{faxseparator}{ --> }
\setkomavar{phoneseparator}{~:~}
\setkomavar{subjectseparator}{ >>> }


%% Customize fonts
%% Use LaTeX's standard font commands
%% Modify with \setkomafont or \addtokomafont
%% (see KOMA documentation)
\setkomafont{backaddress}{\rmfamily}
%\setkomafont{descriptionlabel}{}
\setkomafont{fromaddress}{\small}
%\setkomafont{fromname}{\scshape}
%\setkomafont{pagefoot}{}
%\setkomafont{pagehead}{}
%\setkomafont{pagenumber}{}
%\setkomafont{subject}{}
%\setkomafont{title}{}

\providecaptionname{french}\emailname{Courriel}

% Fin lttscr2opt.tex
%%\revision$Header: /home/ubntjjr/Documents/LaTeX/Courrier/publipost.tex,v 0.0 2012/12/13 08:56:26 ubntjjr Exp$


\begin{document}
\pagestyle{empty}

\setkomavar{place}{Angers}%
\setkomavar{date}{le 13 décembre 2012}%

\setkomavar{fromname}{Gérard \textsc{Menfin}}
\setkomavar{fromaddress}{26 rue des longs boyaux\\49140 Trélazé}
\setkomavar{fromphone}{0670~945~371}
\setkomavar{fromemail}{gerardmenfin@gmail.com}
% \setkomavar{fromurl}{www.gerardmenfin.fr}
\setkomavar{backaddress}{}
\setkomavar{signature}{\qquad\qquad\qquad\qquad\qquad%
  \qquad\qquad\qquad\qquad\qquad%
  \qquad Gérard \textsc{Menfin}}

\setkomavar{subject}{Publipostage, test.}%
%
%
% Chargement de la base depuis fichier csv
\DTLloaddb[
%noheader,%
keys={NM,PN,SX,AD,CP,VI,SD}%
%,headers={Nom,Prénom,Sexe,Adresse,Code%
%  postal,Ville,Solde},%
%,omitlines=1
]{adresses}{adresses.csv}

\begin{DTLenvforeach*}%
 [\not{\DTLiseq{\Nom}{Vorcer}}]% Sélection des lignes
  {adresses}% Base de donnée
  {\Nom=NM,\Prenom=PN,\Sexe=SX,\Adresse=AD,\CodePostal=CP,\Ville=VI,\Solde=SD}% Descripteurs
% Début lettre  
  \begin{letter}{\DTLifeq{\Sexe}{f}{Mme}{M.} \textsc{\Nom} %
      \Prenom{}\\\Adresse{} \\\CodePostal{} \Ville{}}%
%
      \FPabs{\result}{\Solde}%
%      
    \opening{ \DTLifeq{\Sexe}{f}{Chère Madame}{Cher Monsieur}
      \textsc{\Nom}}
%
    Vous en êtes un\DTLifeq{\Sexe}{f}{e}{} autre.\par
%
    Je vous prie de vérifier les informations que nous avons sur vous
    en notre possession:
    \begin{center}
      \begin{tabular}{p{2cm}ccc}
        Adresse&Code postal&Ville&Solde compte\\
        \Adresse&\CodePostal&\Ville&\numprint[EUR]{\Solde}\\
      \end{tabular}
    \end{center}
%
  
    \DTLifeq{\Solde}{}{Comme vous pouvez le constater, vous n'avez
      aucune dette}%
    {\DTLifnumgt{\Solde{}}{0}%
      {J'ai le plaisir de vous rembourser la somme de
        \numprint[EUR]{\result}.}%
      {Je vous prie de bien vouloir nous régler au plus vite votre
        dette de \numprint[EUR]{\result}}{}}
%
    \closing{Recevez, \DTLifeq{\Sexe}{f}{chère Madame}{cher Monsieur}
      , mes sincères salutations}
%
    \DTLifnumgt{\Solde{}}{0}%
  {\encl{Chèque de \numprint[EUR]{\result} }}{}
  %   
  \end{letter}
\end{DTLenvforeach*}

\end{document}

%%%  Local Variables:
%%%  coding: utf-8
%%%  eval: (TeX-PDF-mode 1)
%%%  End:            

Et mon fichier d'adresses (sauvegarder comme adresses.csv)

"Aibavet","Jean","m","17 rue Deschoux","49380","Ladignac sur Rondelle","22.5"
"Quillouch","Marie","f","5 Av Duchamps","75020","PARIS","0.15"
"Havrante","Hélène","f","22 bd Lablague","19140","St Merd les Oussines","-12.75"
"Mamobe","Alfonse","m","15 square Ledoux","13520","Ste Foix la Grande","15.75"
"Comsicomsa","Eva","f","Le Matin","12220","Alaselle","3.85"
"Vorcer","Eva","f","48 rue du haut pressoir","29100","BREST","-21.40"
"Vorcer","Paola","f","48 rue du haut pressoir","29100","BREST","6.15"
"Vorcer","Clement","m","48 rue du haut pressoir","29100","BREST","5.24"
"Vorcer","Maeva","f","48 rue du haut pressoir","29100","BREST","-2.65"
"Vorcer","Aude","f","48 rue du haut pressoir","29100","BREST","11.80"
"Vorcer","Anne","f","48 rue du haut pressoir","29100","BREST",
"Vorcer","Marc","m","48 rue du haut pressoir","29100","BREST",
"Vorcer","Sanson","m","48 rue du haut pressoir","29100","BREST",
"Vorcer","Marie","f","48 rue du haut pressoir","29100","BREST",
"Vorcer","Pascal","m","48 rue du haut pressoir","29100","BREST",
"Vorcer","Eddie","m","48 rue du haut pressoir","29100","BREST",

--
JJR.

Hors ligne

#5 Le 18/11/2013, à 12:28

Spirale21

Re : sed et références arrières

merci gigiair et tu pourrais me dire la différence entre

 /!\([^!]*\)!/ et /!\(.*\)!/

dans mon sed, parce que à mes yeux c pareil alors que pour sed non big_smile.
ça veut dire toute chaine de caractères entre des ! pour les deux sauf que dans ta versions c'est tout les caractères sauf '!'. Merci pour ton modèle de publipostage mais ça m'a l'air bigrement complexe.... je préfère mon programme big_smile


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#6 Le 18/11/2013, à 12:46

pingouinux

Re : sed et références arrières

Bonjour,
Voici un exemple pour comprendre :

$ cat mon_script
sed 's/!\(.*\)!/<Début>\1<Fin>/g' <<<"Il fait beau aujourd'hui !ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit! "
sed 's/!\([^!]*\)!/<Début>\1<Fin>/g' <<<"Il fait beau aujourd'hui !ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit! "

$ ./mon_script
Il fait beau aujourd'hui <Début>ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit<Fin> 
Il fait beau aujourd'hui <Début>ville<Fin>, je suis sous le <Début>temps<Fin> et <Début>parent<Fin> profite pleinement de <Début>endroit<Fin> 

Dans un cas, on part du premier ! jusqu'au dernier de la ligne, dans l'autre, on traite les paires de ! consécutifs.

Hors ligne

#7 Le 18/11/2013, à 13:00

gigiair

Re : sed et références arrières

.* c'est tout caractère (y compris ! donc) tandis que [^!]* c'est tout caractère non !.
Il y a une option que je ne maîtrise pas trop bien, c'est la reconnaissance gourmande (greedy) ou non. dans ton modèle, elle doit être gourmande, c'est à dire que ton ! du gabarit ne s'unifie pas au premier caractère ! rencontré.
Enfin chais pas trop, je sais que ma façon de faire est la bonne (et la plus logique). C'est ce que j'emploie quand je veux remplacer "....." par «....» avec des retour chariot potentiels entre les deux. Tout autre façon de faire échoue, car .* s'arrête obligatoirement à une fin de ligne.

Mon exemple n'est pas très compliqué, mais il suppose la connaissance de scrlttr2, plus souple que lettre AMA. L'usage de datatool permet de faire des alternatives, courantes dans le publipostage (Monsieur|Madame) des extractions partielles, etc... Il faut lire la doc de datatool

texdoc datatool

Si tu veux l'équivalent à coup de script, ça va être largement aussi compliqué.
J'avais ça sous la main, c'est pour ceux que ça intéresse.


--
JJR.

Hors ligne

#8 Le 18/11/2013, à 23:13

Spirale21

Re : sed et références arrières

pour le sed j'entrevois merci pingouinux, oui une ligne se termine par /n et par par un . lol mais pourquoi

sed 's/!\[^!]*!/<Début>\1<Fin>/g'

n'est pas équivalent à

sed 's/![.]*\)!/<Début>\1<Fin>/g' 

là il y a <Début> et <Fin> nul part, sed ne match pas?
gigiair oui je vais lire la doc mais c moins fun parceque je l'ai pas fait mais c clair que ça pourrait me servir


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#9 Le 19/11/2013, à 00:05

aduxas

Re : sed et références arrières

Attention, \[ veut dire le caractère "crochet ouvrant" tandis que [ ouvre une liste de caractères individuels.  Donc
![.]*  veut dire : un point d'exclamation suivi d'un nombre quelconque de points;
!.* veut dire : un point d'exclamation suivi d'un nombre quelconque de caractères quelconques;
!\.* est égal à ![.]*;
![^!]* veut dire un point d'exclamation suivi d'un nombre quelconque de caractères quelconques SAUF un point d'exclamation.

On voit souvent dans des scripts sed "séparateur ouvrant - suivi de tout sauf séparateur fermant - suivi de séparateur fermant" pour isoler des entités délimitées.

Hors ligne

#10 Le 19/11/2013, à 09:27

Spirale21

Re : sed et références arrières

merci aduxas je comprends.. dernière question peut on dire à sed un point d'exlamation suivit par des caractères quelconque? pour moi ça se traduisait par

sed 's/![.]*\)!/

mais le . est traduit comme un caractère '.' et pas comme métacaractère qui veut dire n'importe quel caractère... ça s'éclaire dans ma tête


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#11 Le 19/11/2013, à 09:52

pingouinux

Re : sed et références arrières

Spirale21 #10 a écrit :

peut on dire à sed un point d'exlamation suivit par des caractères quelconque?

! suivi de 0, 1 ou plusieurs caractères quelconques

sed 's/!.*/chaîne_de_remplacement/'

Hors ligne

#12 Le 19/11/2013, à 11:16

gigiair

Re : sed et références arrières

Pour moi «.» matche tous les caractères (y compris «!» ) sauf un caractère de fin de ligne.
Je n'ai rien trouvé dans le info sed à ce sujet, mais dans le info des regexp d'emacs c'est précisé.

info regexps a écrit :

`.' (Period)
     is a special character that matches any single character except a
     newline.  For example, the regular expressions `a.b' matches any
     three-character string that begins with `a' and ends with `b'.

`*'
     <snip>
     The matcher processes a `*' construct by matching, immediately, as
     many repetitions as can be found.  Then it continues with the rest
     of the pattern.  If that fails, backtracking occurs, discarding
     some of the matches of the `*'-modified construct in case that
     makes it possible to match the rest of the pattern.

Ce qui fait que pour le texte original

 Il fait beau aujourd'hui !ville!, je suis sous le !temps! et !parent! profite pleinement de !endroit! 

!\(.*\)! capture tout le texte entre le premier «!» et le dernier «!»

sauf s'il y a une fin de ligne entre les deux.
AMHA ça doit être le cas du fichier du PO, car je n'arrive à retrouver son retour que si j'insère des fins de ligne dans le texte aux bons endroits.
C'est la seule façon qui m'a permis de retrouver le retour du PO.


--
JJR.

Hors ligne

#13 Le 19/11/2013, à 13:48

Spirale21

Re : sed et références arrières

je me suis mal exprimé: est il possible de capturer ce qu'il y'a entre 2 ! d'un même mot... au lieu de mettre

sed 's/!\[^!]*!/<Début>\1<Fin>/g'

mettre un métacaractère dans les crochets pour signifier tout types de caractères... pour avoir un mot qui est entre !

ex: récupérer !ville! dans:  il fait beau dans !ville! merci de le demander


il y a trois manière de faire: la bonne, la mauvaise et la mienne

Hors ligne

#14 Le 19/11/2013, à 14:00

Postmortem

Re : sed et références arrières

C'est ça que tu veux :

$ sed 's/.*!\([^!]*\)!.*/\1/' <<< 'il fait beau dans !ville! merci de le demander'
ville

?


Trusty Tahr (64 bits), Athlon64 3800+, ATI Radeon HD4870

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

Haut de page ↑