Remplacer du texte en boucle....

Résolu/Fermé
AlexMac - 28 oct. 2011 à 10:34
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 - 31 oct. 2011 à 11:18
Bonjour,

Alors voila mon petit soucis. J'ai un script tout simple pour remplacer du texte dans le fichier contenant la ligne suivante :
)(())((()))(()))

je voudrais éliminer tous les couples () de telle sorte qu'a la fin il ne me reste que :
))

Pour l'instant j'ai juste :
sed "s/()//g"

mais ca me donne :

)()(())())

De nouveaux couples () se sont formés et si je veux les éliminer il faut retaper la commande sed "s/()//g"

etc...

Donc je cherche un moyen d'exécuter cette commande autant de fois que nécessaire, jusqu'à ce qu'il n'y ait plus de couple ()...

Comme j'ai plusieurs fichier qui ont des tailles différentes, je voudrais que cette "boucle" tourne autant de fois que nécessaire sur chacun.

Je vous remercie beaucoup pour votre aide

Alex

5 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 419
28 oct. 2011 à 11:58
Salut,

$ echo ")(())((()))(()))" | sed ':z;s/()//;tz'
))

$

;-))
1
Franzux Messages postés 8907 Date d'inscription mercredi 5 décembre 2007 Statut Contributeur Dernière intervention 27 octobre 2015 1 145
28 oct. 2011 à 12:13
Soit dans une boucle :

franzux@maerix:~/test/parenthese$ for i in 'ls *.txt';do echo ${i};cat ${i};done
parentheses1.txt
)(())((()))(()))
parentheses2.txt
)(())((()))(())))(())((()))(())) )(())((()))(())) 
parentheses3.txt
)(())((()))(())) 
)(())((()))(())) )(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(())) 
franzux@maerix:~/test/parenthese$ cat script.sh 
#!/bin/bash

for file in *.txt
do
	echo  "Traitement de ${file}..."
	sed -i ':z;s/()//;tz' ${file}
done
franzux@maerix:~/test/parenthese$ ./script.sh 
Traitement de parentheses1.txt...
Traitement de parentheses2.txt...
Traitement de parentheses3.txt...
franzux@maerix:~/test/parenthese$ for i in 'ls *.txt';do echo ${i};cat ${i};done
parentheses1.txt
))
parentheses2.txt
)))) )) 
parentheses3.txt
)) 
)) )) )) 
)) )) 
)) )) )) 
)) )) 


Bon courage ;)
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 419
28 oct. 2011 à 12:21
Salut,

Y'a des courageux ;-))

$ ls
fic1  fic2  fic3

$ cat fic1
)(())((()))(()))

$ cat fic2
)(())((()))(())))(())((()))(())) )(())((()))(()))

$ cat fic3
)(())((()))(())) 
)(())((()))(())) )(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(())) )(())((()))(())) 
)(())((()))(())) )(())((()))(()))

$ sed -si.bak ':z;s/()//;tz' fic*

$ ls
fic1  fic1.bak  fic2  fic2.bak  fic3  fic3.bak

$ cat fic1
))

$ cat fic2
)))) ))

$ cat fic3
)) 
)) )) )) 
)) )) 
)) )) )) 
)) ))

$ 

;-))
0
OK merci à tous pour vos réponses.
Ce week-end je n'ai pas accès a mon ordi.
J'essaie tout ça lundi et je vous tiens au courant.

Merci beaucoup

Alexandre
0
Youpiiii, ma journee commence super bien !

Ca fonctionne avec sed -i
Et merci pour l'astuce du sed -si.bak. Comme ca je peux garder mon fichier original.

Ce serait super sympa si vous pouviez m'expliquer un peu comment fonctionne ce script : je ne comprends pas le :z;....;tz

Merci beucoup

Alexandre
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 419
31 oct. 2011 à 09:32
:z
Étiquette. On définit une étiquette afin de s'y brancher dessus et de pouvoir faire une boucle. On peut l'appeler comme on veut (:boucle ou :toto etc.).

tz
La commande "t" est une commande de branchement conditionnel et permet de se brancher sur l'étiquette définie, si et seulement si la commande de substitution précédente a réussi.

Il existe d'autres commandes de branchement, notamment la commande "b" qui elle est une commande de branchement inconditionnel.

il y a aussi la commande "T", qui à l'instar de son homologue "t", n'effectue un branchement sur l'étiquette pointée, que si la commande précédente a échoué.

-s
Permet de prendre en compte chaque fichier passé en argument individuellement. Si on omet ce paramètre et dans le cas de plusieurs fichiers donnés en argument, "sed" traite l'ensemble de ces fichiers comme un seul et unique flux de données.


Pour davantage de précisions sur ces commandes, voir la FAQ sur SED

;-))
0
Merci pour cette reponse complete et claire !
Je vais consulter la FAQ.

Alex
0

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
Modifié par lami20j le 31/10/2011 à 10:59
Salut,
:~$ echo ")(())((()))(()))" | sed 's/.*\(..\)$/\1/' 
)) 
:~$ echo ")(())((()))(()))" | sed 's/[()]*\(..\)$/\1/' 
))


lami20j
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 419
31 oct. 2011 à 11:10
Salut,

Oui mais ça ne tient pas compte de la demande initiale, à savoir "je voudrais éliminer tous les couples () de telle sorte qu'a la fin il ne me reste que : )) ", ce n'est pas un nombre défini qu'il faut avoir, mais toutes les parenthèses orphelines...

Donc si on rajoute une ")" à la fin (ou ailleurs), voilà ce que ça donne :

$ echo ")(())((()))(())))" | sed 's/.*\(..\)$/\1/' 
))

$ echo ")(())((()))(())))" | sed ':z;s/()//;tz'
)))

$

;-))
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 569
31 oct. 2011 à 11:18
Oups, j'ai mal compris. Tu as raison ;-)
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 419
31 oct. 2011 à 11:18
Pas de souci, ça peut toujours servir ;-))
0