Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 08/09/2019, à 17: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, à 17: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, à 18: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, à 18: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, à 18: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, à 18: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, à 18:35

pingouinux

Re : Remplacement de chaine

Montre quelques lignes en exemple.

Hors ligne

#6 Le 08/09/2019, à 18:45

Christophe C

Re : Remplacement de chaine

Non, j'ai fini par y arriver ... sans bien comprendre smile

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, à 08: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, à 19: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 )

En ligne

#8 Le 08/09/2019, à 19: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, à 08: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, à 08: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, à 11: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, à 12: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, à 14: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) :

https://github.com/koalaman/shellcheck/wiki/SC2086 a écrit :

"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, à 15: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, à 16: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