Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
Rmplacement de variables ligne à ligne
Envoyé par: lhags

Bonjour à tous,

voila la description de ce que je n'arrive pas à coder en ksh pour l'instant

j'ai comme fichier source (fichier 1) une suite de ligne du même format :
MRS-DB-00001;SADMORCHK02D01;8;MRS-DB-00001#JADMORCHK02AH;0800;;;;0500;;;;;;;1830;SUPPR;;;;
MRS-DB-00001;SADMORRMA01D01;0;;0030;;; everyday;;;;;;;;;;;;

Je souhaite avoir comme fichier cible (fichier 2) :
BCK-DB-00001;SADMORCHK02D01;8;BCK-DB-00001#JADMORCHK02AH;0800;;;;0500;;;;;;;1830;SUPPR;;;;
BCK-DB-00001;SADMORRMA01D01;0;;0030;;; everyday;;;;;;;;;;;;

avec un fichier de correspondance (fichier 3)
MRS-DB-00001;BCK-DB-00001
TATADV1;TOTODV1

On voit le remplacement suivant avec un "FS=;" :
champ 1
champ 4 si la variable existe dans le champ
Bien évidemment le champ1 évolue

Une des manières de le coder que je vois :
- on lit le fichier source ligne à ligne (cat fichier1 | while read line)
- on récupère champ 1, on cherche la correspondance dans le fichier3
- idem pour champ4 si existe (avec concaténation de ce qui est après le #)
- on ecrit cette ligne dans le fichier2
- ligne suivante

j'essaye avec awk mais je ne trouve pas la syntaxe adéquate.

J'ai aussi essayé une méthode de remplacement global avec sed option g, mais sans beaucoup plus de résultat.

Si quelqu'un a des pistes pour résoudre ce problème, je suis preneur (oui je sais, je demande du code ...)


Merci à vous

Poste le Wednesday 25 July 2007 16:08:02
Répondre     Citer    
Re: Rmplacement de variables ligne à ligne
Envoyé par: oudoubah

Juste une piste pour ce soir :
Le mieux serait de le faire sous awk.
L'algo serait :

function incremente() {
# faire la fonction qui incrémente compteur, version chaine de caractères
}


BEGIN {compteur="00001"}

{
if (tab[$1] == "" ) { tab[$1]="BCK-DB-" compteur ; incremente() }
gsub ($1,tab[$1]) # Syntaxe sûrement mauvaise. A voir avec la doc
print $0
}

END {
for i in tab {
printf(i, tab, fichier) # syntaxe à revoir
}
}

Le plus pénible à faire reste la fonction incrémente, et de regarder la doc pour la syntaxe.
La doc qui va bien (en anglais) : [www.gnu.org]

Tu as lu les docs. Tu es devenu un informaticien. Que tu le veuilles
ou non. Lire la doc, c'est le Premier et Unique Commandement de
l'informaticien.
-+- TP in: Guide du Linuxien pervers - "L'évangile selon St Thomas"

Poste le Wednesday 25 July 2007 23:23:04
Répondre     Citer    
Re: Rmplacement de variables ligne à ligne
Envoyé par: Sve@r

Citation
lhags
Une des manières de le coder que je vois :
- on lit le fichier source ligne à ligne (cat
fichier1 | while read line)
- on récupère champ 1, on cherche la
correspondance dans le fichier3
- idem pour champ4 si existe (avec concaténation
de ce qui est après le #)
- on ecrit cette ligne dans le fichier2
- ligne suivante

Bon, ben si ton algo te semble correct, ya plus qu'à...
#!/bin/sh
# Préparation canaux input et output
exec 3<fichier1       # Le canal 3 sera associé à fichier 1 en entrée
exec 4>fichier2       # Le canal 4 sera associé à fichier 2 en sortie

# Lecture fichier 1 ligne à ligne
while read line 0<&3
do
    # On récupère champ 1
    c1=`echo $line |cut -f1 -c\;`

    # On cherche correspondance c1 dans fichier 3 (on cherche la ligne débutant par "c1" et suivie de ";")
    cor=`grep "^$c1;" fichier3`
    # Petit détail => il est impératif qu'il n'y ait qu'une ligne correspondant dans fichier 3

    # Si la correspondance y est (variable non vide)
    if test -n "$cor"
    then
        # On récupère le 2° champ de cette correspondance
        c2=`echo $cor |cut -f2 -c\;`

        # A partir de là, j'ai un peu de mal à comprendre comment on passe au fichier 2
        # J'ai l'impression que la ligne du fichier 2 est la même que celle du fichier 1
        # Sauf qu'on a remplacé le champ1 par le champ pris dans le fichier 3
        # Donc si c'est ça, action

        # Ecriture de la ligne du fichier 1 dans fichier2 en remplaçant le champ1 par son correspondant
        echo "$line" |sed -e "s/$c1/$c2/g" 1>>&4
    fi

    # Passage à la ligne suivante
done

Si tu veux le faire en awk, je te laisse te dém.... Moi, pour un truc pareil, je m'en sors mieux en shell (même si ce sera hyper lent). Sinon une solution Python me semble envisageable mais je viens à peine de débuter en python donc mon code risque d'être un peu malhabile

#!/bin/python
# coding: Latin-1 -*-

# Création du tableau de recherche en c1 et c2
f=open("fichier3", "r")
cherche=f.readlines()
f.close()
c1=[]
c2=[]
for line in cherche:
    mots=line.split(";")
    c1.append(mots[0])
    c2.append(mots[1])

# Ouverture fichiers 1 et 2
fi=open("fichier1", "r")
fo=open("fichier2", "w")

# Lecture fichier1
while 1:
    line=fi.readline()
    # Ligne vide => fin de fichier
    if line == "":
        break

    # Découpage de la ligne en mots
    mots=line.split(";")

    # Recherche du mot n° 1 dans le tableau des champs1
    try:
         i=c1.index(mots[0])
    except:
         i=-1

    # Si le mot n° 1 a été trouvé en position "i" dans le tableau des champs1
    if i != -1:
        # Ecriture ligne en remplaçant chaque c1 par son homologue c2
        fo.write(line.replace(c1, c2))

# Fermeture
fi.close()
fo.close()

L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Monday 30 July 2007 17:35:37
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
Rmplacement de variables ligne à ligne
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons