inserer des caractères à une place bien précise dans un document
16 réponses
philippe
Bonjour,
je ne connais pas grand chose à perl mais je pense que vous pourriez
résoudre mon problème.
je dois modifier un fichier texte pour incorporer des donnees dans une base
de données.
il y a 100000 lignes d'où la nécessité d'un script.
il faut creer une copie d'un document texte.txt et y rajouter des 'simple
quotes' (en dessous du 4) :
- après la 4eme virgule,
- avant la 5eme virgule,
- apres la 13eme virgule,
- avant la 14eme virgule.
On Sun, 26 Dec 2004 15:07:53 +0100 philippe wrote:
$t[4]| | =| qq{'$t[4]}| | ; ^ ^ ^ ^ ^
Tu as des caractères bizarres ici. Je pense que c'est un problème ce copier-coller.
auriez vous une petite idée ?
D'autre part: - tu n'avais pas précisé (ou bien j'avais mal lu) qu'il fallait faire ça sur chaque ligne du texte (moi, je l'ai justement fait sur le texte global), - j'avais fait une grosse erreur de logique. :(
La version corrigée (cette fois-ci, je l'ai testée et elle semble fonctionner) est:
<<<<< #!/usr/bin/perl
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Merci Benoit et Jérémy,
vous me sortez une belle épine du pied!
en effet j'avais fait un copier-coller dans vi et ces pipes sont apparus en bleu très foncé et je ne les avais pas vu
serait-ce trop demander comment faire pour remplacer deux virgules qui se suivent par ,une_variable, ex : a,z,e,r,,y,u devient a,z,e,r,tttt,y,u tttt etant la valeur de la variable.
d'avance un très grand merci
Philippe
Jérémy JUST wrote:
On Sun, 26 Dec 2004 15:07:53 +0100
philippe <linux@rousselot.org> wrote:
$t[4]| | =| qq{'$t[4]}| | ;
^ ^ ^ ^ ^
Tu as des caractères bizarres ici. Je pense que c'est un problème ce
copier-coller.
auriez vous une petite idée ?
D'autre part:
- tu n'avais pas précisé (ou bien j'avais mal lu) qu'il fallait faire
ça sur chaque ligne du texte (moi, je l'ai justement fait sur le texte
global),
- j'avais fait une grosse erreur de logique. :(
La version corrigée (cette fois-ci, je l'ai testée et elle semble
fonctionner) est:
<<<<<
#!/usr/bin/perl
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>)
{my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ;
$t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ;
}
Merci Benoit et Jérémy,
vous me sortez une belle épine du pied!
en effet j'avais fait un copier-coller dans vi et ces pipes sont apparus en
bleu très foncé et je ne les avais pas vu
serait-ce trop demander comment faire pour remplacer deux virgules qui se
suivent par ,une_variable,
ex :
a,z,e,r,,y,u devient a,z,e,r,tttt,y,u
tttt etant la valeur de la variable.
On Sun, 26 Dec 2004 15:07:53 +0100 philippe wrote:
$t[4]| | =| qq{'$t[4]}| | ; ^ ^ ^ ^ ^
Tu as des caractères bizarres ici. Je pense que c'est un problème ce copier-coller.
auriez vous une petite idée ?
D'autre part: - tu n'avais pas précisé (ou bien j'avais mal lu) qu'il fallait faire ça sur chaque ligne du texte (moi, je l'ai justement fait sur le texte global), - j'avais fait une grosse erreur de logique. :(
La version corrigée (cette fois-ci, je l'ai testée et elle semble fonctionner) est:
<<<<< #!/usr/bin/perl
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Merci Benoit et Jérémy,
vous me sortez une belle épine du pied!
en effet j'avais fait un copier-coller dans vi et ces pipes sont apparus en bleu très foncé et je ne les avais pas vu
serait-ce trop demander comment faire pour remplacer deux virgules qui se suivent par ,une_variable, ex : a,z,e,r,,y,u devient a,z,e,r,tttt,y,u tttt etant la valeur de la variable.
d'avance un très grand merci
Philippe
Benoit Izac
Bonjour,
le 27/12/2004 à 21:00, philippe a écrit dans le message <cqppk4$m1o$ :
serait-ce trop demander comment faire pour remplacer deux virgules qui se suivent par ,une_variable, ex : a,z,e,r,,y,u devient a,z,e,r,tttt,y,u tttt etant la valeur de la variable.
$var='tttt' s/,,/,$var,/
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur une même ligne) :
while (s/,,/,$var,/g) {}
-- Benoit Izac
Bonjour,
le 27/12/2004 à 21:00, philippe a écrit
dans le message <cqppk4$m1o$1@biggoron.nerim.net> :
serait-ce trop demander comment faire pour remplacer deux virgules qui
se suivent par ,une_variable,
ex :
a,z,e,r,,y,u devient a,z,e,r,tttt,y,u
tttt etant la valeur de la variable.
$var='tttt'
s/,,/,$var,/
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur
une même ligne) :
le 27/12/2004 à 21:00, philippe a écrit dans le message <cqppk4$m1o$ :
serait-ce trop demander comment faire pour remplacer deux virgules qui se suivent par ,une_variable, ex : a,z,e,r,,y,u devient a,z,e,r,tttt,y,u tttt etant la valeur de la variable.
$var='tttt' s/,,/,$var,/
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur une même ligne) :
while (s/,,/,$var,/g) {}
-- Benoit Izac
Jérémy JUST
On Mon, 27 Dec 2004 22:08:09 +0100 Benoit Izac wrote:
$var='tttt' s/,,/,$var,/
Oui, mais dans les programmes que nous avons donnés, nous retirons les virgules avant de traiter la chaîne (en la convertissant en tableau), et nous les remettons après. Donc il faut préciser à quel moment faire la substitution.
<<<<< #!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {s/,,/,$var,/g ; # Substitution avant découpage
my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Une autre solution, que je trouve plus explicite, bien que plus compliquée pour un débutant, est:
<<<<< #!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {my @t = split ',', $_ ;
# `map' prend chaque élément de la liste @t, le met dans $_ # et lui applique le code contenu dans le bloc {...}. # Ici, ce code renvoie $var si $_ est égal à la chaîne vide, # ou renvoie $_ autrement. @t = map {($_ eq '') ? $var : $_} @t ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Comme pour le premier post, ces deux solutions viennent à l'esprit suivant que l'on raisonne en terme de virgules ou d'éléments. Dans la première solution, on travaille sur des successions de virgules, ce qui n'est pas très intuitif. Dans la seconde solution, on cherche les éléments vides dans la liste.
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur une même ligne) :
while (s/,,/,$var,/g) {}
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du motif. Donc le while est inutile.
-- Jérémy JUST
On Mon, 27 Dec 2004 22:08:09 +0100
Benoit Izac <use.reply.to@INVALID.ADDRESS> wrote:
$var='tttt'
s/,,/,$var,/
Oui, mais dans les programmes que nous avons donnés, nous retirons les
virgules avant de traiter la chaîne (en la convertissant en tableau), et
nous les remettons après.
Donc il faut préciser à quel moment faire la substitution.
<<<<<
#!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>)
{s/,,/,$var,/g ; # Substitution avant découpage
my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ;
$t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ;
}
Une autre solution, que je trouve plus explicite, bien que plus
compliquée pour un débutant, est:
<<<<<
#!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>)
{my @t = split ',', $_ ;
# `map' prend chaque élément de la liste @t, le met dans $_
# et lui applique le code contenu dans le bloc {...}.
# Ici, ce code renvoie $var si $_ est égal à la chaîne vide,
# ou renvoie $_ autrement.
@t = map {($_ eq '') ? $var : $_} @t ;
$t[4] = qq{'$t[4]'} ;
$t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ;
}
Comme pour le premier post, ces deux solutions viennent à l'esprit
suivant que l'on raisonne en terme de virgules ou d'éléments. Dans la
première solution, on travaille sur des successions de virgules, ce qui
n'est pas très intuitif. Dans la seconde solution, on cherche les
éléments vides dans la liste.
ou éventuellement (si tu peux avoir à faire plusieurs remplacements
sur une même ligne) :
while (s/,,/,$var,/g) {}
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du
motif. Donc le while est inutile.
On Mon, 27 Dec 2004 22:08:09 +0100 Benoit Izac wrote:
$var='tttt' s/,,/,$var,/
Oui, mais dans les programmes que nous avons donnés, nous retirons les virgules avant de traiter la chaîne (en la convertissant en tableau), et nous les remettons après. Donc il faut préciser à quel moment faire la substitution.
<<<<< #!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {s/,,/,$var,/g ; # Substitution avant découpage
my @t = split ',', $_ ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Une autre solution, que je trouve plus explicite, bien que plus compliquée pour un débutant, est:
<<<<< #!/usr/bin/perl
my $var = 'tttt' ;
open(TEXT, 'test2.txt') or die "Cannot open: $!n" ;
while(<TEXT>) {my @t = split ',', $_ ;
# `map' prend chaque élément de la liste @t, le met dans $_ # et lui applique le code contenu dans le bloc {...}. # Ici, ce code renvoie $var si $_ est égal à la chaîne vide, # ou renvoie $_ autrement. @t = map {($_ eq '') ? $var : $_} @t ;
$t[4] = qq{'$t[4]'} ; $t[13] = qq{'$t[13]'} ;
print STDOUT join ',', @t ; }
Comme pour le premier post, ces deux solutions viennent à l'esprit suivant que l'on raisonne en terme de virgules ou d'éléments. Dans la première solution, on travaille sur des successions de virgules, ce qui n'est pas très intuitif. Dans la seconde solution, on cherche les éléments vides dans la liste.
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur une même ligne) :
while (s/,,/,$var,/g) {}
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du motif. Donc le while est inutile.
-- Jérémy JUST
Benoit Izac
Bonjour,
le 27/12/2004 à 23:20, Jérémy JUST a écrit dans le message :
ou éventuellement (si tu peux avoir à faire plusieurs remplacements sur une même ligne) :
while (s/,,/,$var,/g) {}
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du motif. Donc le while est inutile.
D'ailleurs, la meilleure solution reste de faire un « look-ahead » : % echo '1,2,,4,,,7,,,,0' | perl -pe 's/,(?=,)/,_/g' 1,2,_,4,_,_,7,_,_,_,0
voir aussi (s'il peut y avoir des blancs) : s/,s*(?=,)/,_/g
-- Benoit Izac
Jérémy JUST
Tu t'es déjà répondu à toi-même, mais je poste quand même la réponse que j'avais préparée ce matin (je n'ai pas [et ne veux pas] d'accès aux news en écriture depuis le boulot).
On Tue, 28 Dec 2004 00:23:50 +0100 Benoit Izac wrote:
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du motif. Donc le while est inutile.
Il suffit de ne pas reconnaître plus que nécessaire (là, effectivement, les occurrences se marchaient dessus). Pour ça, je propose de vérifier l'existence de la seconde virgule sans la reconnaître véritablement, avec une assertion de longueur nulle:
M'enfin, je persiste à penser que voir une telle ligne comme « une successions de virgules avec des choses entre elles » est beaucoup moins intuitif qu'« une succession de champs séparés par des virgules ».
-- Jérémy JUST
Tu t'es déjà répondu à toi-même, mais je poste quand même la réponse
que j'avais préparée ce matin (je n'ai pas [et ne veux pas] d'accès aux
news en écriture depuis le boulot).
On Tue, 28 Dec 2004 00:23:50 +0100
Benoit Izac <use.reply.to@INVALID.ADDRESS> wrote:
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences
du motif. Donc le while est inutile.
Il suffit de ne pas reconnaître plus que nécessaire (là,
effectivement, les occurrences se marchaient dessus). Pour ça, je
propose de vérifier l'existence de la seconde virgule sans la
reconnaître véritablement, avec une assertion de longueur nulle:
M'enfin, je persiste à penser que voir une telle ligne comme « une
successions de virgules avec des choses entre elles » est beaucoup moins
intuitif qu'« une succession de champs séparés par des virgules ».
Tu t'es déjà répondu à toi-même, mais je poste quand même la réponse que j'avais préparée ce matin (je n'ai pas [et ne veux pas] d'accès aux news en écriture depuis le boulot).
On Tue, 28 Dec 2004 00:23:50 +0100 Benoit Izac wrote:
Avec l'option g, l'opérateur s remplace déjà toutes les occurrences du motif. Donc le while est inutile.
Il suffit de ne pas reconnaître plus que nécessaire (là, effectivement, les occurrences se marchaient dessus). Pour ça, je propose de vérifier l'existence de la seconde virgule sans la reconnaître véritablement, avec une assertion de longueur nulle:
M'enfin, je persiste à penser que voir une telle ligne comme « une successions de virgules avec des choses entre elles » est beaucoup moins intuitif qu'« une succession de champs séparés par des virgules ».