Issue
I have a source file.txt that i need to be generated and (his content) reformated in a target file.
Here is my source file :
TABLE;APGFPOLI;
Contrat;CHAR(16);Numéro du contrat
Libelle;CHAR(30);Libellé du contrat
DtCreation;CHAR(8);Date de création
DtMaj;CHAR(8);Date de dernière MAJ
DtEffet;CHAR(8);Date d'effet adhésion
MotifAdh;CHAR(2);Motif d'adhésion
DtRadiation;CHAR(8);Date de radiation
DtEnrRad;CHAR(8);Date enregistrement radiat
MotifRad;CHAR(2);Motif de radiation
MtPrime;Numérique 8.2;Montant prime d'origine
DtEffetSusp;CHAR(8);Date d'effet de suspension
DtFinSusp;CHAR(8);Date de fin de suspension
MotifSusp;CHAR(2);Motif de suspension
DestBord;CHAR(1);Destinataire du bordereau
CdDest;CHAR(5);Code du destinataire
NivRupBord;CHAR(1);Niveau rupture bordereau
BordCETIP;CHAR(1);Bordereau CTIP
EnvBordNom;CHAR(1);Envoi bordereau nominatif
Indice;CHAR(2);Indice appliqué
Echeance;CHAR(2);Echéance de l'indice (MM)
Effectif;CHAR(5);Effectif
CdRegr;CHAR(3);Code regroupement 1
CdGroupe;CHAR(3);Code regroupement 2
Periodicite;CHAR(1);Périodicité
Terme;CHAR(1);Terme
Produit;CHAR(6);Code produit affecté
Inspecteur;CHAR(5);Inspecteur
CleInsp;CHAR(1);Clé inspecteur
Filler;CHAR(6);Filler
And this the output that i want :
01 APGFPOLI.
* Numéro du contrat
05 Contrat PIC X(16).
* Libellé du contrat
05 Libelle PIC X(30).
* Date de création
05 DtCreation PIC X(8).
* Date de dernière MAJ
05 DtMaj PIC X(8).
* Date d'effet adhésion
05 DtEffet PIC X(8).
* Motif d'adhésion
05 MotifAdh PIC X(2).
* Date de radiation
05 DtRadiation PIC X(8).
* Date enregistrement radiat
05 DtEnrRad PIC X(8).
* Motif de radiation
05 MotifRad PIC X(2).
* Montant prime d'origine
05 MtPrime PIC 9(8).v9(2)..
* Date d'effet de suspension
05 DtEffetSusp PIC X(8).
* Date de fin de suspension
05 DtFinSusp PIC X(8).
* Motif de suspension
05 MotifSusp PIC X(2).
* Destinataire du bordereau
05 DestBord PIC X(1).
* Code du destinataire
05 CdDest PIC X(5).
* Niveau rupture bordereau
05 NivRupBord PIC X(1).
* Bordereau CTIP
05 BordCETIP PIC X(1).
* Envoi bordereau nominatif
05 EnvBordNom PIC X(1).
* Indice appliqué
05 Indice PIC X(2).
* Echéance de l'indice (MM).
05 Echeance PIC X(2).
* Effectif
05 Effectif PIC X(5).
* Code regroupement 1
05 CdRegr PIC X(3).
* Code regroupement 2
05 CdGroupe PIC X(3).
* Périodicité
05 Periodicite PIC X(1).
* Terme
05 Terme PIC X(1).
* Code produit affecté
05 Produit PIC X(6).
* Inspecteur
05 Inspecteur PIC X(5).
* Clé inspecteur
05 CleInsp PIC X(1).
* Filler
05 Filler PIC X(6).
So being a newbie in the unix shells, what i did is using sed to do that. But when i used sed with the -i option it changed my source file and i ABSOLUTELY do not want that. So i removed it, but the problem now is that my output is not like the one that i want.
Here is my shell :
#!/bin/bash
#Fichier Source
fichier="APGFPOLI.des.txt"
champAdd="05 "
firstAdd="01 "
if [[ -f "$fichier" ]]
then
# read it
sed "1s/TABLE/$firstAdd /" $fichier |sed 's/CHAR/PIC X/' $fichier | sed -E '/Numérique/s/;Numérique\s+([^;]*)/;PIC 9(\1)/' $fichier | while IFS=';' read -r nomChamp format libelle
do
echo \* $libelle
echo $nomChamp $format.
done > test.txt
fi
And here is the output that i have :
*
TABLE APGFPOLI.
* Numéro du contrat
Contrat CHAR(16).
* Libellé du contrat
Libelle CHAR(30).
* Date de création
DtCreation CHAR(8).
* Date de dernière MAJ
DtMaj CHAR(8).
* Date d'effet adhésion
DtEffet CHAR(8).
* Motif d'adhésion
MotifAdh CHAR(2).
* Date de radiation
DtRadiation CHAR(8).
* Date enregistrement radiat
DtEnrRad CHAR(8).
* Motif de radiation
MotifRad CHAR(2).
* Montant prime d'origine
MtPrime PIC 9(8.2).
* Date d'effet de suspension
DtEffetSusp CHAR(8).
* Date de fin de suspension
DtFinSusp CHAR(8).
* Motif de suspension
MotifSusp CHAR(2).
* Destinataire du bordereau
DestBord CHAR(1).
* Code du destinataire
CdDest CHAR(5).
* Niveau rupture bordereau
NivRupBord CHAR(1).
* Bordereau CTIP
BordCETIP CHAR(1).
* Envoi bordereau nominatif
EnvBordNom CHAR(1).
* Indice appliqué
Indice CHAR(2).
* Echéance de l'indice (MM)
Echeance CHAR(2).
* Effectif
Effectif CHAR(5).
* Code regroupement 1
CdRegr CHAR(3).
* Code regroupement 2
CdGroupe CHAR(3).
* Périodicité
Periodicite CHAR(1).
* Terme
Terme CHAR(1).
* Code produit affecté
Produit CHAR(6).
* Inspecteur
Inspecteur CHAR(5).
* Clé inspecteur
CleInsp CHAR(1).
As you can see, first thing is that my sed changes are not here, and the output is missing the last line of my source file. I am now stuck thinking of a way to achieve what i want.
Solution
If you specify an input file ($fichier
) for sed
it will not read from stdin
, so the result of the first sed
command is ignored when you use
sed "1s/TABLE/$firstAdd /" $fichier |sed 's/CHAR/PIC X/' $fichier | ...
use
sed "1s/TABLE/$firstAdd /" "$fichier" |sed 's/CHAR/PIC X/' | sed -E '/Numérique/s/;Numérique\s+([^;]*)/;PIC 9(\1)/' | ...
or specify multiple commands for one invocation of sed
sed -E -e "1s/TABLE/$firstAdd /" -e 's/CHAR/PIC X/' -e '/Numérique/s/;Numérique\s+([^;]*)/;PIC 9(\1)/' "$fichier" | ...
It might be easier to implement this with awk
.
awk -F ';' '$1=="TABLE" && $3=="" {printf "01 %s.\n\n", $2; next} {sub(/CHAR/,"PIC X", $2);printf " * %s.\n\n 05 %s %s.\n\n", $3, $1, $2;}' APGFPOLI.des.txt > test.txt
Explanation:
-F ';'
field separator;
$1=="TABLE" && $3==""
detectTABLE
line. Alternative: Check for record number 1 (FNR==1
)printf "01 %s.\n\n", $2
formatted outputnext
Skip further processing of this record. Avoids a condition for the next commands.sub(/CHAR/,"PIC X", $2)
replaceCHAR
printf " * %s.\n\n 05 %s %s.\n\n", $3, $1, $2
formatted output.
If necessary you could add variables for 01
and 05
.
awk -F ';' -v 'champAdd=05' -v 'firstAdd=01' '$1=="TABLE" && $3=="" {printf "%s %s.\n\n", firstAdd, $2; next} {sub(/CHAR/,"PIC X", $2);printf " * %s.\n\n %s %s %s.\n\n", $3, champAdd, $1, $2;}' APGFPOLI.des.txt > test.txt
The awk
solution above does not replace the string Numérique ...
.
The following command includes this but works only with GNU awk
because of the gensub
command. Without this command it would require more code to do the replacement in case the numbers after Numérique
can vary. For constant numbers it would be easy to replace one exact string with another using one sub
command.
awk -F ';' -v 'champAdd=05' -v 'firstAdd=01' '$1=="TABLE" && $3=="" {printf "%s %s.\n\n", firstAdd, $2; next} {sub(/CHAR/,"PIC X", $2);$2=gensub(/Numérique ([0-9]*)\.([0-9]*)/,"PIC 9(\\1).v9(\\2)",1,$2);printf " * %s.\n\n %s %s %s.\n\n", $3, champAdd, $1, $2;}' APGFPOLI.des.txt > test.txt
(You can use the same gensub
command in the script version without variables champAdd
etc.)
Answered By - Bodo Answer Checked By - Mildred Charles (WPSolving Admin)