parcours de fichier

parcours de fichier - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 03-05-2006 à 21:20:54    

Bonjour,
 
J'essaye de me dépatouiller avec des scripts shell mais je n'y arrive pas vraiment.
Je veux 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 a modifés ont la forme pour mettre des commentaires
[fichier]
*************************
*
* ceci est le fichier *
* qui n'a pas de sens *
*************************
int void () ...
*{ blalalalall
*
}*
...
[/fichier]
Ce que j'ai choisit pour faire cela c'est je parcours les fichiers un par un et je les réécrit  dans un autre fichier avec un while read et à chaque fois que je vois *{ je n'écris plus dans le fichier temporaire.
Pb :
1- Les fichiers possedent des * et ceci sont remplacés par les fichiers du path courant (surtout les ceux de fin de ligne)  
A cause des * de fin de ligne je modifie le fichier initial de manière érroné et il y a également les quotes qui engendrent une incomprehension.
2- Second point c'est que pour vérifié que la ligne ne contient pas *{ ou }* je fais une usine à gaz avec un grep que je teste afin de voir s'il est vide ou pas.
 
Comment faire pour résoudre ces problèmes ?  
Y a t'il une solution simple et efficace qui peut être différente des scripts (script plus léger avec awk meme si je ne vois pas  ?
 
Merci d'avance
c

Reply

Marsh Posté le 03-05-2006 à 21:20:54   

Reply

Marsh Posté le 04-05-2006 à 13:35:38    

montres nous ton scritp déjà pour qu'on puisse t'aider....
 
mais une structure :


for i in * ; do
    cat $i | grep -v "^\*{" > /tmp/$i.modified
   # plus tous les autres filtrages en |blabla|foo|bar|
done


doit fonctionner  
 
tu as surement oublié de proteger de l'interpretation le caractere * avec un "\" non ?
 
 
mais pour ce genre de manipulation anarchique dans un fichier le plus simple est propre à la fois reste d'appeler un interpreteur comme perl,sed,vi ou awk
 
exemple avec vi sur un fichier bidon :


*{toto}*
*{
toto
}*


 


vi -c "g/^\*{/s/\*{.*}\*/\*{}\*/|:wq" bidon


 
on obtient


*{}*
*{
toto
}*


 
il suffit d'ajouter un deuxième traitement pour faire le multiligne et un script comme ceci :
 


for i in * ; do  
vi -c "g/^\*{/s/\*{.*}\*/\*{}\*/|:wq" $i
vi -c ".............filtre pour gerer le cas sur plusieurs lignes...............|:wq" $i
done


 


Message édité par francoispgp le 04-05-2006 à 13:43:44
Reply

Marsh Posté le 04-05-2006 à 14:05:05    

Reply

Marsh Posté le 04-05-2006 à 14:51:11    

C'est une tâche parfaite pour sed, ça.

/\*{/ {   # si on trouve l'ouverture d'un commentaire...
  :loop
  /}\*/ { b end }  # si on trouve la fin d'un commentaire on va a :end
  N                # sinon on concatene la ligne suivante
  b loop           # on retourne à :loop
  :end
  s/\(.*\)\*{.*}\*\(.*\)/\1\2/  #on efface ce qui est en commentaire
  /^[:blank:]*$/d              #on efface uen éventuelle ligne vide  
}

sed -f effacer_commentaires.sed tonfichier
 
(je n'ai testé que sur ton exemple, mais ça doit être à peu près correct).

Reply

Marsh Posté le 04-05-2006 à 14:51:35    

C'est une tâche parfaite pour sed, ça.

/\*{/ {   # si on trouve l'ouverture d'un commentaire...
  :loop
  /}\*/ { b end }  # si on trouve la fin d'un commentaire on va a :end
  N                # sinon on concatene la ligne suivante
  b loop           # on retourne à :loop
  :end
  s/\(.*\)\*{.*}\*\(.*\)/\1\2/  #on efface ce qui est en commentaire
  /^[[:blank:]]*$/d              #on efface uen éventuelle ligne vide  
}

sed -f effacer_commentaires.sed tonfichier
 
(je n'ai testé que sur ton exemple, mais ça doit être à peu près correct).

Reply

Marsh Posté le 04-05-2006 à 15:31:20    

Bravo tu je revenai sur le topic pour donner une solution extremement proche de la tienne Pillow.  
 
que ce soit sous vi ou sed c'est kifki c'est la même syntaxe puisque ce sont des expressions régulières.

Reply

Marsh Posté le 04-05-2006 à 20:39:52    

Merci pour vos réponses.
En fait mon script est très simple mais la partie supprimant ce que je voudrais ne marche pas.
En fait ce que je veux faire c'est pour un fichier comme celui là
********
* fichier *
*******
function ()
*{toto
* include copy
}*
* ceci doit être conserver
ça aussi
 
*{
* toto a enlever
toto a conserver
}*
titi a conserver
 
J'ai voulu, vu les différentes conditions faire un script

Code :
  1. while read line
  2. do
  3. if test line = "*{" then
  4. aenlever='O' 
  5. else
  6. if line = "*}" then
  7. aenlever='N'
  8. fi
  9. case $line in
  10.    "\*{" )  # marche pas bien vu que caratère spécial unix astérisque et accolade!
  11.      aenlever='O'
  12.      aconserver = 'N'
  13.       ;;
  14.    "\*}" )
  15.      aenlever='N'
  16.       ;;
  17.     "\*" )
  18.        if test aenlever='O'then
  19.           aconserver = 'N'
  20.        else
  21.           aconserver = 'O'
  22.        fi
  23.       ;;
  24.       )
  25.         aconserver = 'O'
  26.       ;;
  27. esac
  28. if aenlever = 'N' and aconserver = 'O' then
  29. echo $line > fichier-out.txt
  30. fi
  31. done <fichier.txt


 
et sinon j'ai essayé autour de cela
sed "\*{*\}\*/d" fichier.txt > fichier_out.txt
mais cela ne donne rien. J'efface trop ou pas assez!
Sur le net j'ai vu une possiblité avec awk + un BEGIN ...END mais je n'ai pas compris comment cela marchais. En plus je pense qu'il y a plus simple.
Voila, je galère pas mal
Encore merci d'avance

Reply

Marsh Posté le 04-05-2006 à 20:41:26    

résultat attendu à partir du fichier précedement cité :
 
********
* fichier *
*******
function ()
* ceci doit être conserver
ça aussi
toto a conserver
titi a conserver  

Reply

Marsh Posté le 04-05-2006 à 20:51:07    

Et pour finir le script ne fonctionne pas et pour plusieurs raisons.
Le read n'aime pas les astérisques de fin de ligne, il les remplace par tout ce qui se trouve dans le répertoire courant ainsi la ligne
* fichier * devient
* fichier script.sh fichier.txt.... ce qui n'est pas vraiment utilisable
ensuite je ne suis pas convaincu des test $line = "*{" , $line= "*}" et $line ="*" vu que ces chaines se trouvent dans une ligne et pas forcement au début, en fin ou au milieu.  
Plus j'y pense plus c'est galère!


Message édité par canardpc le 04-05-2006 à 20:51:31
Reply

Marsh Posté le 04-05-2006 à 21:30:57    

Jovalise : developpe tout petit programme specifique relativement simple "en Ada" en 24 a 48 gratuitement dans la mesure de mes competances sur demande explicite !

Reply

Marsh Posté le 04-05-2006 à 21:30:57   

Reply

Marsh Posté le 05-05-2006 à 10:32:12    

utilises les syntaxes correctes déjà en protégeant tes * et { (toutes) ça aidera
 
qaund au script sed/vi il fonctionne bien donc tu n'a pas du le tester completement, (testé sur 2 distrib linux et tru64unix)
faut adapter pour certaines mais il suffit de respecter les syntaxes et expressions régulières.


Message édité par francoispgp le 05-05-2006 à 10:59:10
Reply

Marsh Posté le 05-05-2006 à 21:45:27    

Effectivement je n'ai pas testé le script de pillow enfin de manière correcte.  
En fait ne connaissant pas bien les commandes unix et sed j'ai taper sed puis son expression régulière mais cela n'a rien donner, alors je me suis dis que ce n'était pas bon d'autant plus que pour moi une expression régulière ne pouvait pas vraiment cela vu que la suppression était conditionné.
Autant pour moi.  
Donc merci pillow et à toi aussi.
J'ai repris son expression en faisant ce qui était indiqué et même si cela ne fonctionne pas c'est assez proche et je vais me dépatouiller avec cela.
Encore merci et je vous tiendrais au courant lorsque j'aurais effectivement trouver ce que je cherchais.

Reply

Marsh Posté le 07-05-2006 à 01:25:24    

Bonsoir,
malgré de nombreux essai et lecture cela ne fonctionne pas.
J'ai essayé de le faire sans les caractères spéciaux et d'effacer tout ce qu'il y a entre < et > si il a µ sinon rien en m'inspirant de ce que pillox a écrit et cela ne donne rien.
Je n'arrive pas à lui conserver ce qui est dans entre < et > et effacer.
Exemple :
µ  a garder
< effacer
a garder
µ effacer
>
a garder
< effacer
µ effacer
effacer >
fichier résultat attendu :
µ  a garder
a garder
a garder
 

Code :
  1. #effacer tout entre < et >
  2. /</ {
  3. :loop
  4. />/ {b end}
  5. N
  6. b loop
  7. :end
  8. s/\(<.*\)µ{.*}\(>\)/\1\2/


J'efface soit trop ou pas suivant ce que je modifie assez. La c'est rien
et si je remplace s/\(<.*\)µ\(>.*\)/\1\2/ par s/<[^<>]*>//g j'efface ce qui est demandé mais trop. J'avais ce résultat aussi sans utiliser de script...
J'ai essayé aussi avec s/\(.*\)µ\(.*\)/\1\2/ ce qui semble logique vu que je veux garder tous ce qui est entre < et > et qui ne commence pas par µ hors il ne se passe rien.
Pourtant les expressions 1 et expressions 2 qui represente donc les lignes entre devrait être conserver et virer µ mais non.


Message édité par canardpc le 07-05-2006 à 01:33:06
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed