Shell - Report d'1 champ sur plusieurs lignes

coco44 -  
 coco44 -
Bonjour,

J'ai un fichier à format fixe que je dois charger sous Oracle en SQL*Loader. Mon fichier contient différents types de lignes (défini par le 1er caractère) : une ligne d'entête (type A) et des lignes de détail (type B ou C). Avant le chargement, le fichier est découpé en 3 : les entêtes d'un côté et les 2 différents types de détail de l'autre, qui partiront vers 3 tables différentes ensuite sous Oracle.

Problème : je dois reporter un champ de la ligne d'entête vers ses lignes de détails. Et impossible de le faire après sous Oracle car ce champ sert justement à faire le lien entre les 2 tables. L'ordre du fichier est séquentiel soit :
A Entête1 Champ_a_reporter
B Détail1
C Détail1
A Entête2 Champ_a_reporter
B Détail2
...

=> L'objectif est donc de reporter un champ de la ligne de type A vers toutes ses lignes de types autres que A (soit celles qui précèdent la prochaine ligne de type A).

Est-ce réalisable en shell ? et si oui je veux bien un peu d'aide parce que je sèche là :?

Merci d'avance

4 réponses

  1. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    hllo
    $ cat a1
    A Entête1 Champ_a_reporter1
    B Détail1
    C Détail1
    A Entête2 Champ_a_reporter2
    B Détail2
    $ 
    $ awk '/^A/ {c=$3;print;next} {print $0, c} ' a1
    A Entête1 Champ_a_reporter1
    B Détail1 Champ_a_reporter1
    C Détail1 Champ_a_reporter1
    A Entête2 Champ_a_reporter2
    B Détail2 Champ_a_reporter2
    $ 
    
    2
  2. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
     
    Salut,

    Voilà un exemple avec "sed". Je pars du principe que le champ à reporter est le dernier sur la ligne, qu'il ne comporte pas d'espace dans son libellé et que les lignes d'en tête commencent toujours par "A" :

    $ cat plop
    A Entête1 Champ_a_reporter1
    B Détail1
    C Détail1
    A Entête2 Champ_a_reporter2
    B Détail2
    C Détail2
    A Entête1 Champ_a_reporter3
    B Détail3
    C Détail3
    
    $ sed ':t;/^A/{h;s/.* //;x;:z;n;/^A/!{G;s/\n/ /;bz}};bt' plop
    A Entête1 Champ_a_reporter1
    B Détail1 Champ_a_reporter1
    C Détail1 Champ_a_reporter1
    A Entête2 Champ_a_reporter2
    B Détail2 Champ_a_reporter2
    C Détail2 Champ_a_reporter2
    A Entête1 Champ_a_reporter3
    B Détail3 Champ_a_reporter3
    C Détail3 Champ_a_reporter3
    
    $

    ;-))
    0
    1. coco44
       
      J'ai l'erreur suivante à l'execution de la commande, est-ce du à ma version de sed ou d'Unix ?

      sed : 0602-417 L'étiquette :t;/^A/{h;s/.* //;x;:z;n;/^A/!{G;s/\n/ /;bz}};bt comporte plus de huit caractères.d
      0
    2. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Quel système (AIX, Solaris, BSD, Gnu/Linux) ?
      Quelle version de "sed" (sed --version) ?
      0
    3. coco44
       
      il ne me reconnait pas la commande sed --version
      et je suis sous AIX v5.
      0
  3. coco44
     
    merci pour vos réponses. En fait le champ à reporter est à la position 572 (jusqu'à 576). C'est un fichier à format fixe. Du coup avec awk j'ai un peu de mal à adapter la commande.
    0
  4. coco44
     
    c'est bon j'ai réussi avec substr :
    awk '/^A/ {c=substr($0, 11, 17);print;next} {print $0, c} ' al
    0