[shell] modifier fin de fichier

Résolu/Fermé
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 2 juin 2009 à 14:37
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 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.
A voir également:

11 réponses

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 567
3 juin 2009 à 09:37
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.
1
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
2 juin 2009 à 14:56
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$
;-))
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
2 juin 2009 à 14:59
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$
;-))
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
2 juin 2009 à 16:55
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.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
2 juin 2009 à 16:59
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) ;-\
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
3 juin 2009 à 08:43
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
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 juin 2009 à 08:54
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...
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
3 juin 2009 à 09:12
ç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é.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 juin 2009 à 09:16
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 ;-))
0
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 567
3 juin 2009 à 09:17
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)?
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 juin 2009 à 09:19
Salut l'ami ;-))

Non en fait il veut ajouter un \ en fin de ligne, mais on est parti sur de mauvaises bases avec ses explications ;-((
0
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 567 > jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020
3 juin 2009 à 09:40
Re,

Merci ;-)
Oui, j'ai vu ça réponse (message 7).

C'est la confusion classique entre ce qu'on peut remplacer (les assertion positives ou de valeurs non nulles) et les assertion nulle (c'est le cas de l'ancre $, qui ne fait que designer une position dans la chaîne)
Mais, bon il a fini par trouver ce qui est bien ;-)

Ce qui est important c'est de comprendre le mécanisme.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > 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 juin 2009 à 10:27
oui. et merci des explications.
La seule chose que je n'ai pas compris, c'est que chez moi je n'arrive pas à remplacer (réellement) le saut de ligne, comme je l'ai dit au message 2 : sed s/\x0D/Z/ plop ne fait rien.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895 > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
3 juin 2009 à 10:34
Re-

sed s/\x0D/Z/ plop ne fait rien
Normal, \x0D c'est le retour chariot si cher à Windows, la fin de ligne c'est \x0A, et pour en changer il faut comme expliqué dans mon 1er message (comme quoi je n'avais pas tout mal compris quand même ;-)) ) tout mettre sur une seule ligne et changer les marques de fin de ligne par "Z" :
sed ':z;N;$! bz;s/\x0A/Z/g' fichier
0
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 567 > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
3 juin 2009 à 10:35
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
0
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 567
3 juin 2009 à 09:22
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é.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
3 juin 2009 à 09:26
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)
0