Pages : 1
#1 Le 18/11/2013, à 00: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
il y a trois manière de faire: la bonne, la mauvaise et la mienne
Hors ligne
#2 Le 18/11/2013, à 06: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, à 10: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, à 10: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, à 11: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 .
ç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
il y a trois manière de faire: la bonne, la mauvaise et la mienne
Hors ligne
#6 Le 18/11/2013, à 11: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, à 12: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, à 22: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 18/11/2013, à 23: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, à 08: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, à 08:52
- pingouinux
Re : sed et références arrières
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, à 10: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é.
`.' (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, à 12: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, à 13: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
?
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#15 Le 26/04/2015, à 08:41
- Spirale21
Re : sed et références arrières
non, non ma demande primaire était de récupérer juste ville ct pour faire du publipostage donc enlever les caractères des champs "spéciaux"
il y a trois manière de faire: la bonne, la mauvaise et la mienne
Hors ligne