[ksh] remplacer un mot par plusieurs ligne

remplacer un mot par plusieurs ligne [ksh] - Shell/Batch - Programmation

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
Reply

Marsh Posté le 27-02-2005 à 11:42:19   

Reply

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


Message édité par Sve@r le 27-02-2005 à 19:01:19

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

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.

Reply

Marsh Posté le 27-02-2005 à 22:21:36    

phnatomass a écrit :

Un gros merci, mais je vais tester demain au boulot.
Je m'attendais à une solution avec le duo sed/awk.


 
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" )


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

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
 
 

Reply

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

Reply

Marsh Posté le 28-02-2005 à 09:46:16    

phnatomass a écrit :

Finalement j'ai corrigé :
...
Merci encore


 
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
 

Reply

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 :
  1. while read


A la fin du fichier read envoi 0 dc on sort

Sve@r a écrit :


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.


Non car je fait un break après echo $ligne

Sve@r a écrit :


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" ?


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

Reply

Marsh Posté le 01-03-2005 à 07:59:36    

phnatomass a écrit :

Oui il sort  

Code :
  1. while read


A la fin du fichier read envoi 0 dc on sort
 
Non car je fait un break après echo $ligne
 
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


 
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 :bounce: . 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+


Message édité par Sve@r le 01-03-2005 à 10:48:15

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

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