Bonjour,
je dois modifier des fichiers se trouvant dans des répertoires en supprimant tout ce qui est entre *{ et }*.
J'ai essayé différente solution mais j'ai plusieurs problèmes en faisant mon script :
les fichiers ont la forme pour mettre des commentaires
*************************
*
* ceci est le fichier *
* qui n'a pas de sens *
*************************
int void () ...
1°) Je parcours les fichiers et je réécrit tout dans un autre fichier avec un while read mais dans les fichiers il y a des * et ceci sont remplacés par les fichiers du path courant (surtout les ceux de fin de ligne) et à chaque fois que je vois *{ je n'écris plus dans le ficher temporaire.
A cause des * de fin de ligne je modifie le fichier initial de manière érroné et les quotes engendre une incomprehension.
Comment faire pour résoudre ce problème ? Y a t'il une solution simple et efficace ?
Merci d'avance
# Heu précise exactement ce que tu veux...
Posté par Raphaël G. (site web personnel) . Évalué à 2.
*************************
* *
* ceci est le fichier *
*{qui n'a pas de sens}*
*************************
Toin fichier résultat :
*************************
* *
* ceci est le fichier *
*{}*
*************************
Une commande qui te fait ça :
cat test | perl -ne 's/\*{[^}]*}\*/*{}*/; print $_'
les \* c'est un backquote des * qui ont un sens de répétition infinie du terme prédédent dans le premier member d'une expression régulière.
Exemple : [^}]*
On répète autant de fois qu'on veux le motif : ^} soit tout sauf une accolade fermante.
Donc \*{[^}]*}\* marche pour tout motif *{n'importe quo ici}*
Après ça le remplace et ça affiche le résultat dans tout les cas.
Vala en espérant que ça soit suffisant...
[^] # Re: Heu précise exactement ce que tu veux...
Posté par canardpc . Évalué à 1.
merci pour ta réponse mais ce n'est pas tout à fait cela.
fichier test en entrée :
*********************************
* ceci est le fichier qui fait rien*
*********************************
function int ()
*{ ceci ne sert à rien et n'a
* pas de sens et doit être enlever
*}
la suite du code
encore
*{ ceci ne sert à rien et n'a
* pas de sens et doit être enlever*}
fichier attendu :
*********************************
* ceci est le fichier qui fait rien*
*********************************
function int ()
la suite du code
encore
Voila ce qui ce que j'attend.
Je pensais faire avec un cat ou un awk (bof?) et une expression régulière mais je n'y suis pas arrivé.
J'ai testé ce que tu a écrit mais cela ne fait rien.
N'étant pas doué pour les cat j'avais choisit de passer par un script lisant ligne par ligne le fichier mais le read et les astérisques ne font pas ensemble ainsi que les quotes. Les astérisques sont remplacés par les fichiers du répertoire!
J'espère avoir été plus clair cette fois, et merci d'avance pour toute l'aide possible.
c
[^] # Re: Heu précise exactement ce que tu veux...
Posté par canardpc . Évalué à 1.
Merci
c
[^] # Re: Heu précise exactement ce que tu veux...
Posté par philou24 . Évalué à 1.
Voici une solution au problème :
sed '/\*{/,/\*}/ s/.*//g' nom_fichier | grep -v '^$' >nouveau_fichier
Explications :
- /\*{/,/\*}/ : la recherche s'effectue entre les 2 expressions régulières (entre *{ et *}
- s/.*//g : tout est alors supprimé (remplacé par rien)
- grep -v '^$' : les lignes vides sont supprimées
Evident, mais ça m'a demandé pas mal de temps...
[^] # Re: Heu précise exactement ce que tu veux...
Posté par canardpc . Évalué à 1.
merci pour cette proposition mais je n'ai pas été assez clair sur mon problème et j'en suis désolé.
En fait j'avais commencé par faire un petit script, vu les besoins que j'avais, lisant ligne par ligne mais cela n'a pas fonctionner et je suis dans une impasse dans cette voie là à cause des tests d'égalités (une ligne contient "*{" pas forcement au début), je ne connais pas de matches en shell et surtout le read ligne à ligne engendrait des incohérences sur le passage des astérisque.(remplacement de la dernière astérisque par tout ce qu'il y a dans le path courant!!)
Donc je me suis dit qu'il fallait que je trouve une expression régulière permetttant de faire cela mais il me semble que c'est impossible et ce malgré le temps que j'y ai passé!
J'ai trouvé un expression régulière similaire à la tienne mais elle est trop efficace.
Je veux dire par la qu'elle efface - celle que j'avais fait aussi - tout ce qui se trouve en *{ et }* alors qu'il faudrait qu'elle efface les lignes commencant par *{ et contenant *} et toutes celles entre qui commence pas *
En gros
titi
*loulou
{* blablaba
* bloblo
blibli
*toto
*}
tata
doit me rendre :
titi
*loulou
blibli
tata
Voila j'aurais du mettre un exemple plus parlant encore désolé. Je continue à chercher mais c'est pas gagner. Si quelqu'un a une idée que ce soit à l'aide d'une expression régulière avec un awk (que je connais pas) ou un sed ou un moyen que le read ne transforme pas les * de fin de ligne je pourrais réutiliser ceci
[code]
while read line
do
if test line = "*{" then
aenlever='O' else
if line = "*}" then
aenlever='N'
fi
case $line in
"\*{") # marche pas bien vu que caratère spécial unix astérisque et accolade!
aenlever='O'
aconserver = 'N'
;;
"\*}")
aenlever='N'
;;
"\*")
if test aenlever='O'then
aconserver = 'N'
else
aconserver = 'O'
fi
;;
)
aconserver = 'O'
;;
esac
if aenlever = 'N' and aconserver = 'O' then
echo $line > fichier-out.txt
fi
done <fichier.txt
[/code]
C'est pas gagné.
Encore merci
c
[^] # Re: Heu précise exactement ce que tu veux...
Posté par philou24 . Évalué à 1.
Si je comprends bien : tu veux suprimer tout ce qu'il y a entre *{ et *} SAUF les lignes ne commençant pas par un * (ou TOUTES les lignes commençant par un *, y compris celles avec { et }). Ai-je bien compris ?
Si c'est ça, il suffit de légèrement modifier l'expression régulière proposée. Cela donne :
sed '/\*{/,/\*}/ s/\*.*//g' nom_fichier | grep -v '^$' >nouveau_fichier
Cela ne supprimera que les lignes commençant par un * entre *{ et *}.
J'espère avoir compris comme il faut. En tout cas avec tes fichiers de test ça marche, à condition que tu te sois trompré dans la 3ème ligne : {* au lieu de *{.
Courage.
[^] # Re: Heu précise exactement ce que tu veux...
Posté par philou24 . Évalué à 1.
La nuit portant conseil, je me suis aperçu que j'avais oublié le ^ qui permet de ne supprimer que les lignes commençant par * et non toutes les lignes contenant *. Désolé.
Voici la correction :
sed '/\*{/,/\*}/ s/^\*.*//g' nom_fichier | grep -v '^$' >nouveau_fichier
J'espère que ça t'ira.
[^] # Re: Heu précise exactement ce que tu veux...
Posté par canardpc . Évalué à 1.
merci pour ta réponse elle correspond à ce que je recherchais.
Celle qui fonctionne c'est la première
sed '/\*{/,/\*}/ s/\*.*//g' nom_fichier | grep -v '^$' >nouveau_fichier
J'ai essayé bien des trucs et rien ne marchais par exemple des script sed vu qu'il fallait un condtionnement.
script.sed
/\*{/ {
:loop
/}\*/ {b end}
N
b loop
:end
s/\(\*{.*\)\*\(.*}\*\)/\1\2/
/^[:blank:]*$/d
}
puis sed -f script.sed < old > nouveau
Un temps fou pour rien et j'ai au moins appris des trucs sur sed :-)
Encore merci une solution "simple" et efficace.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.