[Vi]
Résolu/Fermé
A voir également:
- Vi rechercher un mot
- Rechercher ou entrer l'adresse - Guide
- Trousseau mot de passe iphone - Guide
- Rechercher un mot dans word - Guide
- Voir mot de passe wifi android - Guide
- Mettre un mot de passe sur un dossier - Guide
9 réponses
par exemple pour en mettre une après chaque mot TITI sans effacer la fin de la ligne
vi -c "S/TITI.*/ &/" nomdufichier
le plus simple pour adapter à ton besoi et de consulter le
"Guide de survie sous VI"
http://matrix.samizdat.net/pratique/documentation/guide-survie-VI.html
vi -c "S/TITI.*/ &/" nomdufichier
le plus simple pour adapter à ton besoi et de consulter le
"Guide de survie sous VI"
http://matrix.samizdat.net/pratique/documentation/guide-survie-VI.html
Merci pour ta réponse, mais concretement, je n'ais pas de chaine distinctive... Comme les exemples sont souvent mieux que les ecris je veux faire ca:
fichier de données avec 3 colonnes (ou plus)
1ere : 4 caracteres = 1,05
2eme : 5 = 22,01
3ème : 1 = Y
ca donne :
1,0522,01Y
et je veux :
1,05 22,01 Y
Pour info, j'ai beaucoup de lignes... et beaucoup de colones
Merci de vos aides...
fichier de données avec 3 colonnes (ou plus)
1ere : 4 caracteres = 1,05
2eme : 5 = 22,01
3ème : 1 = Y
ca donne :
1,0522,01Y
et je veux :
1,05 22,01 Y
Pour info, j'ai beaucoup de lignes... et beaucoup de colones
Merci de vos aides...
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
1 098
20 mars 2006 à 16:58
20 mars 2006 à 16:58
Salut,
tu peux utiliser sed.
Avec ton exemple, celà donne :
Une fois que tu as établi ton filtre sed, tu peux traiter tout un fichier avec le paramètre -i
L'ancienne version sera renommée monfichier.txt.old
Dal
tu peux utiliser sed.
Avec ton exemple, celà donne :
$ echo "1,0522,01Y" | sed 's/\(.\{4\}\)\(.\{5\}\)\(.\{1\}\)/\1 \2 \3/' $ 1,05 22,01 Y
Une fois que tu as établi ton filtre sed, tu peux traiter tout un fichier avec le paramètre -i
$ sed -i old 's/\(.\{4\}\)\(.\{5\}\)\(.\{1\}\)/\1 \2 \3/' monfichier.txt
L'ancienne version sera renommée monfichier.txt.old
Dal
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
1 098
20 mars 2006 à 17:08
20 mars 2006 à 17:08
L'expression est compatible avec vi
Donc tu peux aussi faire :
Dal
Donc tu peux aussi faire :
:%s/\(.\{4\}\)\(.\{5\}\)\(.\{1\}\)/\1 \2 \3/
Dal
Mathieu
>
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
20 mars 2006 à 17:46
20 mars 2006 à 17:46
C'est fantastique, c'est exactement ce qu'il me fallait...
MAIS... Mon fichier a 60 champs -> VI me renvoit "E51 : trop de \("
:(
Y a t'il une autre solution ? Combien de \ accepte VI ? Je pourrais tjs essayer de faire 2 ou 3 passes mais...
PS : sur sed, ca marcherait ?
PS2 : je suis sur un PC Windows... :(
MAIS... Mon fichier a 60 champs -> VI me renvoit "E51 : trop de \("
:(
Y a t'il une autre solution ? Combien de \ accepte VI ? Je pourrais tjs essayer de faire 2 ou 3 passes mais...
PS : sur sed, ca marcherait ?
PS2 : je suis sur un PC Windows... :(
jipicy
Messages postés
40842
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 897
>
Mathieu
20 mars 2006 à 19:09
20 mars 2006 à 19:09
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
1 098
>
Mathieu
20 mars 2006 à 20:14
20 mars 2006 à 20:14
60 champs, celà en fait des parenthèses et des slashs... et si ton format change un peu, tu ne t'y retrouves plus.
Tu as intérêt à faire un petit programme pour çà.
Par exemple, en Perl :
@fields est un tableau contenant les positions sur la ligne des caractères après lesquels une tabulation doit être insérée (le premier caractère étant à la position 0).
Dal
Tu as intérêt à faire un petit programme pour çà.
Par exemple, en Perl :
#!/usr/bin/perl @fields = (3,8,9); $st = ""; $o = "0"; open(FICH, "data.txt"); while (<FICH>) { for ($n=0; $n<(length($_)-1); $n++) { $st .= substr($_, $n, 1); if ($fields[$o] eq $n) { $st .= chr(9); $o++; } } print "$st\n"; $st = ""; $o = "0"; } close(FICH);
@fields est un tableau contenant les positions sur la ligne des caractères après lesquels une tabulation doit être insérée (le premier caractère étant à la position 0).
Dal
vi4ever
>
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
21 mars 2006 à 09:59
21 mars 2006 à 09:59
forcément sed appelant vi .....
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
20 mars 2006 à 21:01
20 mars 2006 à 21:01
Bonsoir à tous,
Si j'ai bien compris : Après chaque 4 , 5 et 1 caractère on doit mettre une tabulation.
En ce cas je propose cette solution :
Resultat
Resultat pour Dal
En fait j'ai separe par 4,5 et 1 et ensuite j'afiche ce qui reste de chaine (disons qu'on a 63 caractères). Donc j'affiche 4+5+1 6 fois plus les 3 dernières.
Si j'ai bien compris : Après chaque 4 , 5 et 1 caractère on doit mettre une tabulation.
En ce cas je propose cette solution :
#! /usr/bin/perl use warnings; use strict; while (<DATA>){ my $l = length; print join "\t",unpack("A4A5A1" x ($l/10),$_), substr($_,-($l-(int($l/10))*10)),"\n"; } __END__ 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y3,9999,77A0 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Yaaa 2,0522,01Z2,0522,01Z2,0522,01Z2,0522,01Z2,0522,0
Resultat
[lamitest@localhost corbeille]$ perl ccm_vi.pl 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 3,99 99,77 A 0 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y aaa 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z [lamitest@localhost corbe
Resultat pour Dal
[lamitest@localhost corbeille]$ perl ccm_dal_vi.pl 1,05 22,01 Y 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y3,9999,77A0 1,05 22,01 Y 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Yaaa 2,05 22,01 Z 2,0522,01Z2,0522,01Z2,0522,01Z2,0522,01Z [lamitest@localhost corbei
En fait j'ai separe par 4,5 et 1 et ensuite j'afiche ce qui reste de chaine (disons qu'on a 63 caractères). Donc j'affiche 4+5+1 6 fois plus les 3 dernières.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
20 mars 2006 à 21:29
20 mars 2006 à 21:29
Re,
et même
et même
#! /usr/bin/perl use warnings; while (<DATA>){ s/(.{4})(.{5})(.)/$1\t$2\t$3\t/g; print; } __END__ 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y3,9999,77A0 1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Y1,0522,01Yaaa 2,0522,01Z2,0522,01Z2,0522,01Z2,0522,01Z2,0522,01ZResultat
[lamitest@localhost corbeille]$ perl ccm_vi_2.pl 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 3,99 99,77 A 0 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y 1,05 22,01 Y aaa 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z 2,05 22,01 Z [lamitest@localhost corbeille]$
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
1 098
21 mars 2006 à 09:23
21 mars 2006 à 09:23
Salut Lami20j,
En fait, comme l'a indiqué Mathieu dans son post <5> ( http://www.commentcamarche.net/forum/affich-2154672-vi#5 ), son fichier de données a 60 champs, qui sont de longueur variable (l'exemple donné étant limité à 3 champs) et sans période particulière, semble-t-il.
C'est pourquoi j'ai proposé dans mon script en post <7> ( http://www.commentcamarche.net/forum/affich-2154672-vi#7 ) la création d'un tableau qui contient les positions des champs. Celà me semble être plus facile à gérer (et à faire évoluer si la structure des données venait à changer), plutôt que de coder en dur les sélections à faire sur 60 positions (sous forme d'une expression rationnelle ou autrement).
Il suffit de compléter les 60 positions dans le tableau @fields.
Dal
En fait, comme l'a indiqué Mathieu dans son post <5> ( http://www.commentcamarche.net/forum/affich-2154672-vi#5 ), son fichier de données a 60 champs, qui sont de longueur variable (l'exemple donné étant limité à 3 champs) et sans période particulière, semble-t-il.
C'est pourquoi j'ai proposé dans mon script en post <7> ( http://www.commentcamarche.net/forum/affich-2154672-vi#7 ) la création d'un tableau qui contient les positions des champs. Celà me semble être plus facile à gérer (et à faire évoluer si la structure des données venait à changer), plutôt que de coder en dur les sélections à faire sur 60 positions (sous forme d'une expression rationnelle ou autrement).
Il suffit de compléter les 60 positions dans le tableau @fields.
Dal
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
21 mars 2006 à 12:21
21 mars 2006 à 12:21
Salut Dal,
je comprends ton raisonement. Donc ne tiens pas compte de ce que j'ai dit dans mon message N° 8.
En fait le plus important c'est que TMTOWTDI et Mathieu n'a qu'a choisir la solution que lui convient.
En général je propose d'autres solutions (je parle de Perl) exactement dans cet esprit et en plus je m'entraîne, et je n'ai jamais pensé que ma solution est la meilleure.
Moi aussi j'ai pris note de ta solution mais je me suis arrêtre au 3 champs, donc je n'ai pas vu plus loin (mea culpa).
lami20j
P.S. Mes solutions ne tiennent pas compte de nombre de champs (donc minimum 3 champs.......)
je comprends ton raisonement. Donc ne tiens pas compte de ce que j'ai dit dans mon message N° 8.
En fait le plus important c'est que TMTOWTDI et Mathieu n'a qu'a choisir la solution que lui convient.
En général je propose d'autres solutions (je parle de Perl) exactement dans cet esprit et en plus je m'entraîne, et je n'ai jamais pensé que ma solution est la meilleure.
Moi aussi j'ai pris note de ta solution mais je me suis arrêtre au 3 champs, donc je n'ai pas vu plus loin (mea culpa).
lami20j
P.S. Mes solutions ne tiennent pas compte de nombre de champs (donc minimum 3 champs.......)
[Dal]
Messages postés
6203
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 janvier 2025
1 098
21 mars 2006 à 14:41
21 mars 2006 à 14:41
Salut Lami20j,
Tu as raison, surtout avec Perl, il y a toujours de multiples façons de traiter un problème.
A vrai dire, j'aime bien ton idée d'utiliser unpack avec join (j'avais d'ailleurs initialement pensé à utiliser split avec join, mais l'expression sur 60 positions ne m'attirait pas trop). Elle exploite mieux les spécificités de Perl. De plus, elle utilise la longueur de chaque champ (ce qui semble être l'information dont dispose Mathieu), et non leur position.
Celà fait aussi un code plus court, et le format de description de la structure reste relativement lisible "A4A5A1..." (pas vraiment moins qu'un tableau).
Pour répondre à la question de Mathieu avec ta méthode, on pourrai faire comme çà :
$stFieldsTemplate = "A4A5A1";
à compléter sur les 60 positions avec la suite des Axx..., puisqu'elles sont arbitraires et en tout cas non périodiques, et dans la boucle un simple :
print join "\t",unpack($stFieldsTemplate,$_); print "\n";
Ton avis m'intéresse, mon utilisation de Perl n'étant pas aussi avancée, et tes interventions sur ce langage étant toujours très instructives :)
Dal
Tu as raison, surtout avec Perl, il y a toujours de multiples façons de traiter un problème.
A vrai dire, j'aime bien ton idée d'utiliser unpack avec join (j'avais d'ailleurs initialement pensé à utiliser split avec join, mais l'expression sur 60 positions ne m'attirait pas trop). Elle exploite mieux les spécificités de Perl. De plus, elle utilise la longueur de chaque champ (ce qui semble être l'information dont dispose Mathieu), et non leur position.
Celà fait aussi un code plus court, et le format de description de la structure reste relativement lisible "A4A5A1..." (pas vraiment moins qu'un tableau).
Pour répondre à la question de Mathieu avec ta méthode, on pourrai faire comme çà :
$stFieldsTemplate = "A4A5A1";
à compléter sur les 60 positions avec la suite des Axx..., puisqu'elles sont arbitraires et en tout cas non périodiques, et dans la boucle un simple :
print join "\t",unpack($stFieldsTemplate,$_); print "\n";
Ton avis m'intéresse, mon utilisation de Perl n'étant pas aussi avancée, et tes interventions sur ce langage étant toujours très instructives :)
Dal
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
21 mars 2006 à 17:02
21 mars 2006 à 17:02
Re,
Pour suivre ton raisonnement, on pourra même créer une fonction
qui pourra être utiliser un peu dans la manière que ton tableau @fields, avec la difference qu'on va utiliser unpack et les valeurs utiliser seront des arguments pour la fonction et pas des éléments d'un tableau.
Une autre posibilité qui me vient à l'esprit c'est de couper la chaîne par 10caractères, et ensuite de traiter le bloc de 10(en 4,5,1), et ce qui reste si longuer > 4 et <=9 (4,5 ou le reste) et si <= 4 (4 ou le reste).
Pour suivre ton raisonnement, on pourra même créer une fonction
sub coup2format { }
qui pourra être utiliser un peu dans la manière que ton tableau @fields, avec la difference qu'on va utiliser unpack et les valeurs utiliser seront des arguments pour la fonction et pas des éléments d'un tableau.
while (<FIC>){ coup2format(arg1,arg2,arg3,......); }Et tu ça pour la paresse dont on parle en Perl (on evite de taper A4A5A1.....)
Une autre posibilité qui me vient à l'esprit c'est de couper la chaîne par 10caractères, et ensuite de traiter le bloc de 10(en 4,5,1), et ce qui reste si longuer > 4 et <=9 (4,5 ou le reste) et si <= 4 (4 ou le reste).