AWK le cri du désespoir
Résolu
fgtp
Messages postés
2
Date d'inscription
Statut
Membre
Dernière intervention
-
asevere Messages postés 13095 Date d'inscription Statut Webmaster Dernière intervention -
asevere Messages postés 13095 Date d'inscription Statut Webmaster Dernière intervention -
Bonjour,
Je suis novice et j'essaie d'utiliser awk (je suis même pas sûr que cela soit réalisable avec cette commande) pour réaliser une concaténation de fichier + une substitution de variables.
En regardant les nombreuses réponses du forum , je n'ai pas réussi à trouver un cas suffisament similaire pour m'indiquer la commande "magique".
Le traitement désiré est le suivant :
4 fichiers en entrée :
* le premier comporte les variables qui seront nécessaires pour valoriser les 3 autres. Sa structure est la suivante :
3 lignes mais n colonnes séparateur "|" (pipe)
exemple :
WORKFLOWS|WORKFLOWS|WORKFLOWS|FOLDER
RBD1|RBD1|RBD1|RBD2
FOL1|FOL2|FOL3|FOL1
* 3 fichiers appelés en fonction du contenu de la valeur de première ligne:
pour la première colonne :
Si valeur = WORKFLOWS alors chargement du fichier /template/fichier1 et substitution de deux variables fichier1.var1 par RBD1 puis fichier1.var2 par FOL1
on recommence pour la seconde colonne , etc..:
Si valeur = WORKFLOWS alors chargement du fichier /template/fichier1 et substitution de deux variable fichier1.var1 par RBD1 puis fichier1.var2 par FOL1
Si la valeur = FOLDER alors chargement du fichier /template/fichier2 et substitution de deux variable fichier2.var1 par RBD2 puis fichier2.var2 par FOL1
etc..
Les n colonnes générant alors n fichiers temporaires valorisés que je n'aurais plus qu'à concaténer.
Je ne sais si cela est assez clair ou précis. Un merci par avance à celui qui peut apporter son aide.
FGTP
Je suis novice et j'essaie d'utiliser awk (je suis même pas sûr que cela soit réalisable avec cette commande) pour réaliser une concaténation de fichier + une substitution de variables.
En regardant les nombreuses réponses du forum , je n'ai pas réussi à trouver un cas suffisament similaire pour m'indiquer la commande "magique".
Le traitement désiré est le suivant :
4 fichiers en entrée :
* le premier comporte les variables qui seront nécessaires pour valoriser les 3 autres. Sa structure est la suivante :
3 lignes mais n colonnes séparateur "|" (pipe)
exemple :
WORKFLOWS|WORKFLOWS|WORKFLOWS|FOLDER
RBD1|RBD1|RBD1|RBD2
FOL1|FOL2|FOL3|FOL1
* 3 fichiers appelés en fonction du contenu de la valeur de première ligne:
pour la première colonne :
Si valeur = WORKFLOWS alors chargement du fichier /template/fichier1 et substitution de deux variables fichier1.var1 par RBD1 puis fichier1.var2 par FOL1
on recommence pour la seconde colonne , etc..:
Si valeur = WORKFLOWS alors chargement du fichier /template/fichier1 et substitution de deux variable fichier1.var1 par RBD1 puis fichier1.var2 par FOL1
Si la valeur = FOLDER alors chargement du fichier /template/fichier2 et substitution de deux variable fichier2.var1 par RBD2 puis fichier2.var2 par FOL1
etc..
Les n colonnes générant alors n fichiers temporaires valorisés que je n'aurais plus qu'à concaténer.
Je ne sais si cela est assez clair ou précis. Un merci par avance à celui qui peut apporter son aide.
FGTP
4 réponses
Salut,
Il nous faut des exemples plus parlants, comme le contenu des fichiers à modifier (avant et après).
Si j'ai bien compris, chaque champ de la 1ère ligne est lié avec les champs respectifs des lignes 2 et 3 ? Ou pas (autrement dit j'ai rien compris) ?
Il nous faut des exemples plus parlants, comme le contenu des fichiers à modifier (avant et après).
Si j'ai bien compris, chaque champ de la 1ère ligne est lié avec les champs respectifs des lignes 2 et 3 ? Ou pas (autrement dit j'ai rien compris) ?
Bonjour Jipicy,
Effectivement, ce n'est pas très clair. Je suis pas sur de faire mieux. Encore merci de ton aide.
fichier 1 ou les informations sont liées en colonne , il peut y avoir n colonnes (exemple colonne 1 : Workflows RBD1 et FOL1 m'intéressent)
WORKFLOWS|WORKFLOWS|WORKFLOWS|FOLDER|MAPPING
RBD1|RBD1|RBD1|RBD2|TOTO
FOL1|FOL2|FOL3|FOL1|TITI
fichier 2 ./template/buildworkflows.ksh appelé si la premiere ligne de la colonne concerné = workflows( 2 variables à valoriser @@WORKFLOWNAME@@ = RBD1 et @@FOLDERNAME@@ = FOL1)
fichier 3 ./template/buildfolder.ksh appelé su la première ligne de la colonne concerné = FOLDER (2 variables à valoriser
@@WORKFLOWNAME@@ =RBD2 et @@FOLDERNAME@@=FOL1)
fichier 4 ./template/buildmapping.ksh appelé su la première ligne de la colonne concerné = MAPPING (2 variables à valoriser
@@WORKFLOWNAME@@ =TOTO et @@FOLDERNAME@@=TITI)
1 fichier de sortie = buildglobal.ksh
Une fois les n colonnes traitées, le résultat de sortie est un fichier concaténé p * fichier2 valorisé + q * fichier3 valorisé + r * fichier4 valorisé (ou p + q + r = n)
exemple avec les 5 colonnes (3 workflows, 1 folder, 1 mapping)
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL1 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL1
....
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL2 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL2
....
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL3 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL3
....
#------------------------------------------------------------------------------
# AJOUT DU FOLDER RBD2.FOL1 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL3
...
#------------------------------------------------------------------------------
# AJOUT DU MAPPING TOTO.TITI A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=TOTO
WORKFLOWNAME=TITI
....
PS : j'ai essayé d'inverser le fichier d'entrée mais je n'y arrive pas mieux afin d'obtenir 3 colonnes et n lignes plutôt que 3 lignes et n colonnes.
Effectivement, ce n'est pas très clair. Je suis pas sur de faire mieux. Encore merci de ton aide.
fichier 1 ou les informations sont liées en colonne , il peut y avoir n colonnes (exemple colonne 1 : Workflows RBD1 et FOL1 m'intéressent)
WORKFLOWS|WORKFLOWS|WORKFLOWS|FOLDER|MAPPING
RBD1|RBD1|RBD1|RBD2|TOTO
FOL1|FOL2|FOL3|FOL1|TITI
fichier 2 ./template/buildworkflows.ksh appelé si la premiere ligne de la colonne concerné = workflows( 2 variables à valoriser @@WORKFLOWNAME@@ = RBD1 et @@FOLDERNAME@@ = FOL1)
fichier 3 ./template/buildfolder.ksh appelé su la première ligne de la colonne concerné = FOLDER (2 variables à valoriser
@@WORKFLOWNAME@@ =RBD2 et @@FOLDERNAME@@=FOL1)
fichier 4 ./template/buildmapping.ksh appelé su la première ligne de la colonne concerné = MAPPING (2 variables à valoriser
@@WORKFLOWNAME@@ =TOTO et @@FOLDERNAME@@=TITI)
1 fichier de sortie = buildglobal.ksh
Une fois les n colonnes traitées, le résultat de sortie est un fichier concaténé p * fichier2 valorisé + q * fichier3 valorisé + r * fichier4 valorisé (ou p + q + r = n)
exemple avec les 5 colonnes (3 workflows, 1 folder, 1 mapping)
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL1 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL1
....
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL2 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL2
....
#------------------------------------------------------------------------------
# AJOUT DU WORKFLOW RBD1.FOL3 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL3
....
#------------------------------------------------------------------------------
# AJOUT DU FOLDER RBD2.FOL1 A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=RBD1
WORKFLOWNAME=FOL3
...
#------------------------------------------------------------------------------
# AJOUT DU MAPPING TOTO.TITI A L'ESPACE DE STOCKAGE
#------------------------------------------------------------------------------
FOLDERNAME=TOTO
WORKFLOWNAME=TITI
....
PS : j'ai essayé d'inverser le fichier d'entrée mais je n'y arrive pas mieux afin d'obtenir 3 colonnes et n lignes plutôt que 3 lignes et n colonnes.
Je suis désolé mais c'est encore moins clair que la 1ère fois ;-((
Bon c'est ok pour le fichier1
Par contre à quoi ressemble tes fichiers et tes variables à changer dans ces fichiers ./template/xxxxxxxxx.ksh ???
Exemple fichier template AVANT => APRÈS
Bon c'est ok pour le fichier1
Par contre à quoi ressemble tes fichiers et tes variables à changer dans ces fichiers ./template/xxxxxxxxx.ksh ???
Exemple fichier template AVANT => APRÈS
Merci à Jipicy pour sa patience. Ce forum est génial.
J'ai trouvé une solution qui consiste à inverser le fichier de $TabETL_PWCT vers $TabETL_PWCT_modif
(peut être pas la plus élégante mais ça marche).
awk 'BEGIN { FS="|"}
{if (NR==1)
{ for (i=1;i<=NF;i++)
{
if ($i=="WORKFLOW") {type[i]="WORKFLOW"}
if ($i=="FOLDER") {type[i]="FOLDER"}
if ($i=="MAPPING") {type[i]="MAPPING"}
NBCOL=NF
}
}
}
{if (NR==2)
{ for (i=1;i<=NBCOL;i++)
workflowName[i]=$i
}
}
{if (NR==3)
{ for (i=1;i<=NBCOL;i++)
folderName[i]=$i
}
}
END { for (i=1;i<=NBCOL;i++)
printf("%s,%s,%s\n",type[i],workflowName[i],folderName[i])
}
' $TabETL_PWCT >> $TabETL_PWCT_modif
cat $TabETL_PWCT_modif | while read ligne
do
type=`echo $ligne | awk -F "," '{print $1}'`
folderName=`echo $ligne | awk -F "," '{print $2}'`
workflowName=`echo $ligne | awk -F "," '{print $3}'`
if [ $type == "FOLDER" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_FOLDER.txt >> $BuildScript
fi
if [ $type == "WORKFLOW" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_WORKFLOW.txt >> $BuildScript
fi
if [ $type == "MAPPING" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_MAPPING.txt >> $BuildScript
fi
done
J'ai trouvé une solution qui consiste à inverser le fichier de $TabETL_PWCT vers $TabETL_PWCT_modif
(peut être pas la plus élégante mais ça marche).
awk 'BEGIN { FS="|"}
{if (NR==1)
{ for (i=1;i<=NF;i++)
{
if ($i=="WORKFLOW") {type[i]="WORKFLOW"}
if ($i=="FOLDER") {type[i]="FOLDER"}
if ($i=="MAPPING") {type[i]="MAPPING"}
NBCOL=NF
}
}
}
{if (NR==2)
{ for (i=1;i<=NBCOL;i++)
workflowName[i]=$i
}
}
{if (NR==3)
{ for (i=1;i<=NBCOL;i++)
folderName[i]=$i
}
}
END { for (i=1;i<=NBCOL;i++)
printf("%s,%s,%s\n",type[i],workflowName[i],folderName[i])
}
' $TabETL_PWCT >> $TabETL_PWCT_modif
cat $TabETL_PWCT_modif | while read ligne
do
type=`echo $ligne | awk -F "," '{print $1}'`
folderName=`echo $ligne | awk -F "," '{print $2}'`
workflowName=`echo $ligne | awk -F "," '{print $3}'`
if [ $type == "FOLDER" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_FOLDER.txt >> $BuildScript
fi
if [ $type == "WORKFLOW" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_WORKFLOW.txt >> $BuildScript
fi
if [ $type == "MAPPING" ]
then
sed -e "s/@@FOLDERNAME@@/$folderName/g" -e "s/@@WORKFLOWNAME@@/$workflowName/g" $templateDir/DLVR_BUILD_PCRS_MAPPING.txt >> $BuildScript
fi
done
Effectivement, c'est plus logique, d'avoir les données par lignes que par colonnes sachant que awk, sed & Cie travaillent sur des lignes et non sur des colonnes.
Ceci dit, une petite suggestion pour convertir le fichier:
Ensuite, on utilise sed pour remplacer les pipes par des retour chariots dnas les fichier tmp_split-* (sed n'est pas obligatoire, mais là, c'est un moyen rapide de faire la transformation sans generer trop de fichier temporaire)
Enfin, on recolle les fichiers tmp_split* et on nettoie le repertoire courant.
C'est a mon avis plus rapide que awk (je n'ai pas tester, mais je le pré-sent) et c'est en tout cas plus lisible que ta manip ;-)
Ceci dit, une petite suggestion pour convertir le fichier:
split -l1 fichier.txt tmp_split- sed -i 's/|/\ /g' tmp_split-* paste -d'|' tmp_split-* >fichier.res rm -f tmp_split-*On commence par faire un split du fichier en précisant de couper toues les "une ligne" et de placer le resultat dans tmp_split-aa(ab, ac, ad, etc.)
Ensuite, on utilise sed pour remplacer les pipes par des retour chariots dnas les fichier tmp_split-* (sed n'est pas obligatoire, mais là, c'est un moyen rapide de faire la transformation sans generer trop de fichier temporaire)
Enfin, on recolle les fichiers tmp_split* et on nettoie le repertoire courant.
C'est a mon avis plus rapide que awk (je n'ai pas tester, mais je le pré-sent) et c'est en tout cas plus lisible que ta manip ;-)