Pages : 1
#1 Le 08/09/2019, à 16:56
- Christophe C
Remplacement de chaine
bon, je travaille toujours sur les chaines, et comme d'habitude, c''est ce qui me pose le plus de problème.
Je veux remplacer dans un fichier des chaines ou j'ai régulièrement un ! suivi d'un espace. je veux les remplacer par un simple séparateur !
Pour tester, je fait cat fichier | sed -e 's/!/X/g' > toto.txt : ça marche.
Par contre quand je veux traiter l'espace, rien ne marche :
cat fichier | sed -e 's/! /!/g' > toto.txt
cat fichier | sed -e 's/\! \/!/g' > toto.txt
cat fichier | sed -e 's/!\ \/!/g' > toto.txt
Là je sèche.
Dernière modification par Christophe C (Le 08/09/2019, à 16:57)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#2 Le 08/09/2019, à 17:04
- Christophe C
Re : Remplacement de chaine
Bizarre, si je découpe en tranche ce qu'il y avait en amont, (mais en faisant la même chose), ca semble marcher. C'est peut-être mes opérations amonts qui posent problème, il faut que je creuse.
Dernière modification par Christophe C (Le 08/09/2019, à 17:05)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#3 Le 08/09/2019, à 17:10
- pingouinux
Re : Remplacement de chaine
Bonjour,
La première commande est correcte, les deux suivantes sont erronées (\ devant le /).
Montre éventuellement à quoi ressemble fichier.
Il vaut mieux faire
sed -e 's/! /!/g' fichier> toto.txt
Hors ligne
#4 Le 08/09/2019, à 17:23
- Christophe C
Re : Remplacement de chaine
je pense que mon problème vient du fait que ce n'est pas vraiment un espace mais une fin de ligne. Selon la façon dont j'enchaine mes opérations ça marche ou non. C'est assez strange.
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#5 Le 08/09/2019, à 17:35
- pingouinux
Re : Remplacement de chaine
Montre quelques lignes en exemple.
Hors ligne
#6 Le 08/09/2019, à 17:45
- Christophe C
Re : Remplacement de chaine
Non, j'ai fini par y arriver ... sans bien comprendre
cat toto1.tmp | grep -oP "(?<=Name: ').*(?='; Class)" | sort | uniq | sed 's/.*/&!/' | sed -e 's/! /!/g'
ne marche pas, mais
VAR=$(cat toto1.tmp | grep -oP "(?<=Name: ').*(?='; Class)" | sort | uniq | sed 's/.*/&!/')
echo $VAR > toto2.tmp
cat toto2.tmp | sed -e 's/! /!/g'
marche !
C'est la même suite de commande, mais coupée en 2 ! Apparemment il n'aime pas trop de pipe à la suite.
Je garde une partie des lignes du fichier, je met un "!" au bout, je supprime les doublons, je me retrouve alors avec une longue ligne ou le séparateur n'est pas "!" mais "! " (l'espace doit venir du retour à la ligne). Si je tente de le remplacer dans le pipe, cela ne marche pas, mais dans une ligne séparée, ce foutu " " accepte d'être remplacé !
Dernière modification par Christophe C (Le 09/09/2019, à 07:42)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#7 Le 08/09/2019, à 18:11
- Sciensous
Re : Remplacement de chaine
dans ce cas il suffirait de modifier un peu la ligne de pingouinux:
sed -e 's/!\ \?$/!/g' fichier> toto.txt
le \? indiquant aucun ou 1 du caractère précédent (ici espace)
antiX 19 et 21 et Ubuntu 20.04 et 22.04
( sous LXDE et gnome-shell )
Hors ligne
#8 Le 08/09/2019, à 18:25
- kamaris
Re : Remplacement de chaine
@Christophe C : quand tu as fait
echo $VAR > toto2.tmp
tu as implicitement converti les sauts de lignes en espace. C'est pour ça que sed trouve ensuite des espaces quand tu fais
cat toto2.tmp | sed -e 's/! /!/g'
Si tu veux changer les délimiteurs de lignes de « \n » vers « ! », il serait mieux de faire
grep -oP "(?<=Name: ').*(?='; Class)" toto1.tmp | sort -u | sed -z 's/\n/!/g'
Hors ligne
#9 Le 09/09/2019, à 07:52
- Christophe C
Re : Remplacement de chaine
Ah, c'est pour cela que je dois créer un fichier, cela permet de convertir les retours à la lignes en espace, et donc de les traiter. Ok, ce n'est pas un problème de pipe, mais de caractère spécial qui est éradiqué par la création du fichier tampon. Je me doutais d'un truc comme cela, sans bien le comprendre. C'est désormais plus clair.
Il faut donc que je traite directement le caractère de fin de ligne. merci de cette précision.
Dernière modification par Christophe C (Le 09/09/2019, à 07:53)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#10 Le 09/09/2019, à 10:35
- kamaris
Re : Remplacement de chaine
Non, ce n'est pas l'écriture dans un fichier qui a converti les sauts de lignes en espaces, c'est le
echo $VAR
, car tu n'as pas mis les guillemets de rigueur :
echo "$VAR"
Que tu écrives ensuite dans un fichier, sur la sortie standard, ou dans un pipe, n'a pas d'importance. Par exemple, au lieu de
echo $VAR > toto2.tmp
cat toto2.tmp | sed -e 's/! /!/g'
tu aurais pu faire
echo $VAR | sed -e 's/! /!/g'
avec le même résultat.
Hors ligne
#11 Le 09/09/2019, à 11:56
- Christophe C
Re : Remplacement de chaine
Bon, je ne vois pas la logique de ce comportement, mais ok, merci de l'info. C'est important de le savoir, effectivement.
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#12 Le 09/09/2019, à 13:25
- kamaris
Re : Remplacement de chaine
Voici une explication probablement plus didactique que celle de « man bash » : https://github.com/koalaman/shellcheck/wiki/SC2086
En particulier (en remplaçant $1 par $VAR dans notre cas) :
"echo $1" looks like "print the first argument". It's actually "Split the first argument by IFS (spaces, tabs and line feeds). Expand each of them as if it was a glob. Join all the resulting strings and filenames with spaces. Print the result."
Hors ligne
#13 Le 09/09/2019, à 14:48
- Christophe C
Re : Remplacement de chaine
Oui, cela dit ce que cela fait, mais pas le pourquoi de ce comportement.
Bon, on s'en moque, mais par contre il faut le savoir.
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#14 Le 09/09/2019, à 15:54
- kamaris
Re : Remplacement de chaine
Eh bien, le « pourquoi » est une question peut-être un peu vaste, mais disons que c'est simplement parce que bash est un interpréteur de commandes. Or, pour interpréter, il découpe en mots la chaine de caractères qu'on lui donne, selon les caractères contenus dans la variable spéciale IFS (par défaut espace, tabulation, saut de ligne). C'est son comportement par défaut : si on veut qu'il ne fasse pas ça, c'est-à-dire qu'il n'interprète pas, il faut protéger la chaine de caractères par des guillemets (simples ou doubles, selon le niveau de protection souhaité).
Hors ligne