Home > Software engineering >  Create a target file using the contents of a source file by adding strings to it
Create a target file using the contents of a source file by adding strings to it

Time:12-16

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.

CodePudding user response:

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=="" detect TABLE line. Alternative: Check for record number 1 (FNR==1)
  • printf "01 %s.\n\n", $2 formatted output
  • next Skip further processing of this record. Avoids a condition for the next commands.
  • sub(/CHAR/,"PIC X", $2) replace CHAR
  • 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

CodePudding user response:

This might work for you (GNU sed):

sed -E '1{s/.*;(.*);/01 \1./;b}
        s/(.*);CHAR(.*);(.*)/\n   * \3\n\n     05 \1 PIC X\2./
        s/(.*);Numérique (.*)\.(.*);(.*)/\n   * \4\n\n     05 \1 PIC 9(\2).v9(\3)./' file

Pattern match and format the back references to the required output.

CodePudding user response:

Using sed

$ cat sed.script
1s/[^;]*;\([^;]*\)\?;\?\(.*\)/01 \1/
2,$s/\([^;]*\);[^(]*\(.[0-9]*)\);\(.*\)/\t*\3\n\t05 \1 PIC X\2/
s/\([^;]*\)[^0-9]*\([0-9]*\)\.\([0-9]*\);\(.*\)/\t*\4\n\t05 \1 PIC 9(\2).v9(2)/

To call the script

$ sed -f sed.script input_file > test.txt

Or as a one liner

$ sed '1s/[^;]*;\([^;]*\)\?;\?\(.*\)/01 \1/;2,$s/\([^;]*\);[^(]*\(.[0-9]*)\);\(.*\)/\t*\3\n\t05 \1 PIC X\2/;s/\([^;]*\)[^0-9]*\([0-9]*\)\.\([0-9]*\);\(.*\)/\t*\4\n\t05 \1 PIC 9(\2).v9(2)/' input_file > test.txt

Output

$ sed -f sed.script input_file
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)
  • Related