remplacer un mot par plusieurs ligne [ksh] - Shell/Batch - Programmation
Marsh Posté le 27-02-2005 à 18:58:46
J'ai considéré qu'il pouvait y avoir plusieurs mots par ligne
#!/bin/sh
# Récupération du nom du fichier
fichier=$1
#Découpage de la variable LIST_SRV
old="$IFS"
IFS=","
set $LIST_SRV
IFS="$old"
# Création d'un canal numéroté pour traiter le fichier
exec 3<$fichier
# Balayage du fichier
while true
do
read ligne 0<&3
# Fin de fichier ???
test -z "$ligne" && break
# Balayage de chaque mot de la ligne
for mot in $ligne
do
# Si le mot est "SRVS"
if test "$mot" = "SRVS"
then
# Ecriture des mots de remplacement
for tmp in $*
do
echo $tmp
done
else
# Ecriture du mot inchangé
echo $mot
fi
done
done
# Fin du script
Si jamais il n'y a qu'un mot par ligne, alors tu remplaces la boucle "for mot in $ligne" par les instructions suivantes:
# Si la ligne est "SRVS"
if test "$ligne" = "SRVS"
then
# Ecriture des mots de remplacement
for tmp in $*
do
echo $tmp
done
else
# Ecriture de la ligne inchangée
echo $ligne
fi
Marsh Posté le 27-02-2005 à 22:12:54
Un gros merci, mais je vais tester demain au boulot.
Je m'attendais à une solution avec le duo sed/awk.
Marsh Posté le 27-02-2005 à 22:21:36
phnatomass a écrit : Un gros merci, mais je vais tester demain au boulot. |
sed aurait suffi pour remplacer un mot par un autre. awk peut marcher mais je sais pas trop comment lui faire passer un nombre de mots variable (on ne sait pas à l'avance combien il y aura de mots dans "LIST_SRV" )
Marsh Posté le 27-02-2005 à 23:07:00
En fait il y a 2 bug dans le script.
Le 1er est que si il y a plusieurs mots dans une même ligne du fichiers texte ils sont placé ligne à ligne dans le resultat.
Le 2eme est que seule la premiere occurence de SRVS est remplacé.
Question :
test -z "$ligne" && break
A quoi sert le mot break dans cette ligne ?
Meci
Marsh Posté le 27-02-2005 à 23:29:29
Finalement j'ai corrigé :
#!/bin/sh
# Récupération du nom du fichier
fichier=$1
#Découpage de la variable LIST_SRV
old="$IFS"
IFS=","
set $LIST_SRV
IFS="$old"
# Création d'un canal numéroté pour traiter le fichier
exec 3<$fichier
# Balayage du fichier
while read ligne 0<&3
# Fin de fichier ???
test -z "$ligne"
# Balayage de chaque mot de la ligne
for mot in $ligne
do
# Si le mot est "SRVS"
if test "$mot" = "SRVS"
then
# Ecriture des mots de remplacement
for tmp in $*
do
echo $tmp
done
else
# Ecriture du mot inchangé
echo $ligne
break
fi
done
done
# Fin du script
Merci encore
Marsh Posté le 28-02-2005 à 09:46:16
phnatomass a écrit : Finalement j'ai corrigé : |
Pour répondre à ta 1ère question, le "break" servait à sortir de la boucle "while true" quand la variable "ligne" était vide (donc que la boucle avait lu tout le fichier). Cela peut effectivement générer un bug si ton fichier contient une ligne vide. Ton script corrigé ne sort plus du tout
Ton second bug est en effet vrai. J'y ai pas pensé (j'ai fait ce script de tête sans tester) mais effectivement, si la ligne contient plusieurs mots, ils sont réécrits un par ligne.
Ta correction est un peu foireuse parce que, si la ligne contient plusieurs mots, tu réécrits autant de fois ta ligne qu'il y a de mots à l'intérieur.
Avant de te filer une nouvelle correction, il faudrait réellement savoir
1) y a-t-il un seul mot ou plusieurs mots par ligne
2) s'il y a plusieurs mots, que faire si l'un de ces mots est "SRVS" ? Parce que s'il y a "toto SRVS titi tutu", je ne sais pas trop ce que tu veux en sortie
- soit tu veux
toto titi tutu
server1
server2
server3
- soit tu veux
toto
server1
server2
server3
titi tutu
Marsh Posté le 28-02-2005 à 21:08:53
Sve@r a écrit : Ton script corrigé ne sort plus du tout |
Oui il sort
Code :
|
A la fin du fichier read envoi 0 dc on sort
Sve@r a écrit : |
Non car je fait un break après echo $ligne
Sve@r a écrit : |
En fait j'ai 2 cas mais régler le 2nd règle le 1er.
1er cas le mot est seul sur la ligne
2eme cas Le mot n'est pas seule :ex SRVS toto titi devra se transformer en :
SRV1 toto titi
SRV2 toto titi
SRV3 toto titi
La je croit que ça se complique vraiment.
Par contre ton prog a un petit défaut mais dans mon cas ce n'est pas grave, il supprime les ligne vide.
Merci de ton aide
Marsh Posté le 01-03-2005 à 07:59:36
phnatomass a écrit : Oui il sort
|
Ok - J'ai enregistré - Je fais ça ce matin au boulot et je te l'envoie...
Suite...
Ok - Je l'ai fait et testé. Il est ops.
#!/bin/sh
# Pour tester - A enlever quand test terminé
LIST_SRV="serveur1,serveur2,serveur3"
# Récupération du nom du fichier
fic=$1
# Décomposition LIST_SRV
old="$IFS"
IFS=","
set $LIST_SRV
IFS="$old"
# Création d'un flux numéroté pour lire le fichier
exec 3<"$fic"
# Lecture du fichier
while read ligne 0<&3
do
# Vérification premier mot égal "SRVS"
if test "`echo $ligne |cut -f1 -d' '`" = "SRVS"
then
# Si la ligne a plus d'un mot
if test `echo $ligne |wc -w` -gt 1
then
# Isolation du reste de la ligne
reste=`echo $ligne |cut -f2- -d' '`
else
# Pas de reste
unset reste
fi
# Balayage de la liste de remplacement
for remp in $*
do
# Affichage du mot de remplacement et du reste
echo "$remp $reste"
done
else
# Affichage de la ligne inchangée
echo "$ligne"
fi
done
Magnifique script . Fonctionne même avec les lignes vides
Le petit test pour "reste" était obligatoire parce que si je teste pas le nb de mots et que je remplis "reste" avec les champs "2 etc", ben quand la ligne n'a qu'un mot il est remis dans "reste".
A+
Marsh Posté le 27-02-2005 à 11:42:19
Bonjour,
Dans un script shell ksh, j'ai une variable qui contient un ensemble de mot séparé par une virgule. ex:
LIST_SRV=serveur1,serveur2,server3
maintenant je souhaite remplacer dans un fichier le mot SRVRS par chaque mot ligne à ligne .
Ex fichier originale test.txt
#Liste de serveurs
SRVS
Apres modification par le script
#Liste de serveurs
server1
server2
server3
Merci de votre aide
Message édité par phnatomass le 27-02-2005 à 14:41:34