Menu

[shell] modifier fin de fichier [Résolu/Fermé]

Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
- - Dernière réponse : Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
- 3 juin 2009 à 11:11
Bonjour,
Voilà, j'ai un fichier texte, et je voudrais pouvoir le modifier facilement par quelques lignes de commandes afin d'avoir un texte compatible avec C.
Le but est alors à minima de mettre des \ (backslash) à la fin de chaque ligne.
Comme ça je mets au début soi un const char* soit un #define.
J'écarte toute solution perl ou langage plus évolué, pour des raisons de portabilité (perl n'est pas toujours installer surtout sur cygwin) mais pourquoi pas sed.
J'ai testé
sed -e "s/\xD/Z/g" fichier_test
pour remplacer chaque retour à la ligne par un Z (pour tester avant de mettre un \) mais ça ne fait rien !
Merci de votre aide.
Afficher la suite 

11 réponses

Meilleure réponse
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
3332
1
Merci
Re,

Le problème portait réellement du le remplacement du saut de ligne
Justement, c'est à cause de ça que je ne comprennais pas.
En remplaçant les sauts de lignes, logiquement le fichier résultat ne contiendra qu'une seule ligne (vu que les sauts ont été supprimé.
En fait tu ne veux rien supprimer, tout veux simplement ajouter un caractère à la fin de la chaîne.

Le metacaractère $ qui est en fait une ancre (je me rappellais pas le mot exact qui le défini), correspond à la fin de la chaîne de caractères et cette position se trouve avant le caractère se passage à la ligne

Donc quand on fait s/$/Z/ ça ne veut pas dire qu'on remplace un certain caractère, puisque de toute façon $ ne consomme pas de texte.
En revanche ça veut dire que à la position designée par $ on met un Z

Ce n'est pas la même chose avec \n qui en tant que motif, consomme de texte et s/\n/Z/ veut dire qu'on remplace le saute de ligne avec un Z.

Le plus important avec les regex c'est de comprendre les lire metacaractère par métacaractère et pas dans leur ensemble.

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 42675 internautes nous ont dit merci ce mois-ci

Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504
0
Merci
Salut,
jp@MDK:~/tmpfs ssh$ cat plop
ligne1
ligne2
ligne3
ligne4
ligne5

jp@MDK:~/tmpfs ssh$ cat -A plop
ligne1^M$
ligne2^M$
ligne3^M$
ligne4^M$
ligne5^M$

jp@MDK:~/tmpfs ssh$ sed ':z;N;$! bz;s/\x0D\x0A/Z/g' plop
ligne1Zligne2Zligne3Zligne4Zligne5

jp@MDK:~/tmpfs ssh$ sed ':z;N;$! bz;s#\x0D\x0A#\\#g' plop
ligne1\ligne2\ligne3\ligne4\ligne5

jp@MDK:~/tmpfs ssh$
;-))
Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504
0
Merci
Je ne sais pas pourquoi je suis parti sur cette solution (j'avions mal lu/vu sûrement ;-(( )
jp@MDK:~/tmpfs ssh$ sed 's#\x0D#\\#' plop
ligne1\
ligne2\
ligne3\
ligne4\
ligne5\
jp@MDK:~/tmpfs ssh$
;-))
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072
0
Merci
Salut.
Je te remercie pour ta solution, mais malheuresement, chez moi elle ne fonctionne pas.
J'ai donc mélangé deux des tes solution.
j'utilise cat -A à travers un pipe pour afficher des $ en fin de ligne, et je lui dit de remplacer les $ par des \, mais là encore souci : il me mets bien des \ en fin de ligne, mais il ne me remplace pas les $ du coup, j'ai $\ en fin de ligne.
jipicy
Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504 -
Re-

J'ai donc mélangé deux des tes solution.
Ce qui donne ?...

Il faudrait que tu nous affiches un bout de ton fichier (ou mieux, le mettre sur ci-joint) ;-\
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072
0
Merci
partons de ton fichier (le mien est bidon aussi pour l'instant)
cat -A plop | sed ' s#$#\\#'
et
cat -A plop | sed ' s/$/\\/'
qui donne tout deux le même résultat :
ligne 1$\
ligne 2$\

à noter que je n'ai pas de ^M à la fin de mes lignes en utilisant cat -A
Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504
0
Merci
Re-

Les ^M en fait sont issus d'un fichier passé par "unix2dos", vu que tu parlais de Cygwin j'ai cru bon d'anticiper et de faire les tests sur un fichier formaté avec des fins de lignes à la sauce Windows ;-(

Après c'est normal que tu te retrouves avec des $\ en fin de ligne, l'option -A de "cat" est là pour afficher les caractères non-imprimables, de ce fait la fonction de "sed" ne fait que remplacer (ou "rajouter à" devrais-je dire dans ce cas là) la fin de ligne (et non le caractère lui même) par un anti-slash...
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072
0
Merci
ça y ai, j'ai trouvé la solution.
sed ' s/$/\\/' plop

en fait $ semble interprété comme un caractère spécial correspondant à la fin de ligne dans sed.
Ma première idée était de faire afficher des $ par cat -A et donc de remplacer le caractère $ (une fois affiché, il doit être considéré comme tel) par \.

Pour cygwin, je suis plutôt des gars qui font un dos2unix que l'inverse ;-) donc pas de souci.

Merci de ton aide, seul j'aurai abandonné.
Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504
0
Merci
De rien ;-))

Tu aurais exposé ton problème sans parler de Cygwin et en disant d'emblée que tu voulais ajouter un \ à la fin des lignes, on n'aurait pas autant tergiversé ;-((

Enfin le principal c'est que tu aies trouvé la solution ;-))
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
3332
0
Merci
Salut,

Je ne comprends pas.
Tu veux mettre un Z à la fin de chaque ligne ou remplacer le saute de ligne avec un Z (ce qui transformera ton fichier de plusieurs lignes dans un fichiers avec une seule ligne)?
lami20j
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
3332 > Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
-
Salut,

D'après ce que j'ai compris il n'y a pas de carriage return (x0D) - ascii 13
Peut être que tu devrais essayer le saut de ligne (Line Feed) - ascii 10 => sed 's/\x0A/Z/' plop
Ou si tu as CR suit de LF sed '/\x0D\x0A/Z/' plop
Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072 > Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
-
Arf, je pensais que c'était x0D (13) par défaut dans Linux et non x0A (10)...
Mais ça ne change rien : impossible de tout mettre sur une ligne.
Bouarf, c'est pas grave, je n'en ai pas besoin, c'est par pure curiosité que j'aurai bien voulu comprendre.
Peut être que si sed traite le programme ligne par ligne il omet les saut de ligne et donc ne peut les remplacer ?
lami20j
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
3332 > Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
-
Re,

Peut être que si sed traite le programme ligne par ligne il omet les saut de ligne et donc ne peut les remplacer ?
As-tu essayé la commande de jiipicy?!

Avec perl, ça aurait été plus simple ;-DDD
jipicy
Messages postés
43478
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
17 mars 2018
4504 > lami20j
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
-
Avec perl, ça aurait été plus simple ;-DDD
Normal c'est un truc de faignasse ça ;-DD
Char Snipeur
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072 > lami20j
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
-
Bien vu !
J'avais essayé sed ':z;N;$! bz;s#\x0D\x0A#\\#g' plop
qui ne fonctionnait pas, j'avais donc tenté sed ':z;N;$! bz;s#\x0D#\\#g' plop puis sed ':z;N;$! bz;s/\x0D/Z/g' plop qui ne fonctionnait pas plus. Mais en effet sed ':z;N;$! bz;s/\x0A/Z/g' plop fonctionne.
tout s'explique.
Messages postés
21510
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
8 octobre 2012
3332
0
Merci
Re,

en fait $ semble interprété comme un caractère spécial correspondant à la fin de ligne dans sed.
Ah, d'accord.

En fait $ est un métacaractère qui répresent une assertion nulle, qui designe une position (celle de fin de ligne) dans une regex, que ça soit sed ou autre.

Hier quand j'ai vu ton message j'ai pensé à sed 's/$/Z/' mais comme je n'avais pas des moyens pour tester (au boulot ;-) et aussi je ne comprennais pas exactement ta demande, je n'ai pas répondu vu que jipicy à pris la main.

Ben, c'est bien que tu as trouvé.
Messages postés
9701
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 juillet 2018
1072
0
Merci
désoler de ne pas avoir été clair, mais ce que je veux faire est expliqué dans les premières lignes de mon message.
Si j'ai mis Z, c'est car \ est un caractère spéciale (d'échappement) et que je voulais tester avant tout le remplacement du saut de ligne (une chose à la fois, j'avance petit à petit).
une fois que j'aurai réussi à affecter Z, j'aurai bien trouver la commande pour le \, mais c'était assez indépendant. Le problème portait réellement du le remplacement du saut de ligne (qui d'ailleur au final n'est pas remplacé, il y a juste un \ à la fin, et c'est encore mieux)