Résultats commande AWK

Résolu
pcsystemd Messages postés 734 Statut Membre -  
pcsystemd Messages postés 734 Statut Membre -

Bonjour,

Je traite un fichier pour créer des lignes d'insertion dans une table postgresql comme suit :

awk -F \| -v Q=\' '{ prov=($1~/^ *$/)?"":uid;printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, Q $4 Q) }' file.sql

Résultats : 

INSERT INTO table (uid, co, ref_g, no_gl) VALUES (8369,   21853 ,  2365994980 , ' TERE D'ENL')
INSERT INTO table (uid, co, ref_g, no_gl) VALUES (96113822,   3185 ,          16 , ' AQ J'M')
INSERT INTO table (uid, co, ref_g, no_gl) VALUES (387281422,   9928 ,  14512776 , ' BAI ANS')

Mais j'ai trois soucis dans ma commande AWK :

- Je n'ai pas le ; a la fin de chaque ligne d'INSERT

- J'ai des espaces en trop  après la première côte simple dans le dernier champ. Exemple ( ' TERE D'ENL')

- Pour toutes les chaines avec une simple côte comme par exemple  ' TERE D'ENL' il faudrait que j'ai comme sortie via AWK :  E'TERE D\'ENL

Pour résumer je souhaite avoir  le résultat suivant

INSERT INTO table (uid, co, ref_g, no_gl) VALUES (8369,   21853 ,  2365994980 , E'TERE D\'ENL');
INSERT INTO table (uid, co, ref_g, no_gl) VALUES (96113822,   3185 ,          16 , E'AQ J\'M');
INSERT INTO table (uid, co, ref_g, no_gl) VALUES (387281422,   9928 ,  14512776 , 'BAI ANS');

L'accès au savoir est la première liberté que chaque homme devrait avoir.

7 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     

    Bonjour,

    Je n'ai pas le ; a la fin de chaque ligne d'INSERT

    Eh bien ajoute un ; devant ton \n :-)

    "INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s);\n"

    J'ai des espaces en trop  après la première côte simple dans le dernier champ. Exemple ( ' TERE D'ENL')

    Il faudrait voir le contenu des variables. Sans exemple de file.sql dur à dire. Mais voici un exemple qui illustre une concaténation.

    echo "" | awk '{a="A"; b="B"; print a b a}' # Affiche ABA

    Pour toutes les chaines avec une simple côte comme par exemple  ' TERE D'ENL' il faudrait que j'ai comme sortie via AWK :  E'TERE D\'ENL

    Si j'ai bien compris, tu veux remplacer chaque ' par \' ? Si c'est bien ça, tu peux t'inspirer de cette astuce :

    echo "aujourd'hui" | awk '{s=$0; gsub("\x27", "\\\x27", s); print s}'  # Affiche aujourd\'hui

    Bonne chance

    1
  2. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     

    hello

    pour supprimer les espaces au début ou à la fin d'un champ, mettre comme séparateur    -F " *[|] *"

    $ echo "A | B | C" |awk -F "|" '{print $1 $2 $3}'
    A  B  C
    $ echo "A | B | C" |awk -F " *[|] *" '{print $1 $2 $3}'
    ABC
    1
  3. pcsystemd Messages postés 734 Statut Membre 23
     

    Bonjour,

    Merci à vous deux cela fonctionne sauf concernant le point 3 càd

    - Pour toutes les chaines avec une simple côte comme par exemple  ' TERE D'ENL' il faudrait que j'ai comme sortie via AWK :  E'TERE D\'ENL

    Ce que je souhaite c'est de remplacer toutes les chaines de caractères ayant dans leurs noms une simple côte.

    Exemple :

    ' TERE D'ENL'  par E'TERE D\'ENL'  : 

    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (8369,   21853 ,  2365994980 , E'TERE D\'ENL')

    '9 COSA D'ESE'  par  E'9 COSA D\'ESE'

    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (8369,   21853 ,  2365994980 , E'9 COSA D\'ESE')

    etc..


    0
  4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     

    Bonjour

    Est-ce que ceci répond à ton problème ?

    echo "TERE D'ENL" | awk '{s=$0; gsub("\x27", "\\\x27", s); print "E\x27" s "\x27"}'

    Résultat :

    E'TERE D\'ENL'

    Bonne chance

    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. pcsystemd Messages postés 734 Statut Membre 23
     

    Merci.

    J'ai fais des tests  mais non concluants car je n'arrive pas à intégrer la solution :

    {s=$0; gsub("\x27", "\\\x27", s); print "E\x27" s "\x27"}

     ... dans ma commande AWK ci-dessous :

    awk -F \| -v Q=\' '{ prov=($1~/^ *$/)?"":uid;printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, Q $4 Q) }' file.sql

    Une idée ?


    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
       

      Bonjour,

      Avoir un exemple minimal de file.sql serait idéal, mais si j'ai bien compris ton code, ce que j'ai appelé s et qui était initialisé à $0 correspond dans ton cas $4. Je n'ai pas trop compris à quoi servait la variable prov dans ton script awk (à mon avis elle ne sert à rien) donc du coup je l'ai supprimée dans ce qui suit.

      awk -F \| '{s=$4; gsub("\x27", "\\\x27", s); printf("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, "E\x27" s "\x27")}' file.sql

      file.sql

      Voici ce que j'ai cru deviner de la structure d'une ligne type de ton fichier .sql :

      UID | CO | REF_G | TERE D'ENL

      Résultat de la commande proposée

      awk -F \| '{s=$4; gsub("\x27", "\\\x27", s); printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, "E\x27" s "\x27")}' file.sql
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (0,  CO ,  REF_G , E' TERE D\'ENL')

      Remarque

      • Indépendamment des histoires de awk, je te suspecte d'avoir un dump dans lequel les colonnes sont séparées par des | et que tu veux recharger dans postgresql sauf qu'à cause des séparateurs, tu dois retraiter le fichier pour pouvoir le charger en base.
      • Or normalement si ton dump a été bien construit, tu as directement des directives SQL dedans (c'est ce que ferait mysqldump et j'imagine pg_dump). Et du coup tu n'aurais pas à faire toutes ces bidouilles avec awk.
      • As-tu regardé ?

      Bonne chance

      1
  7. pcsystemd Messages postés 734 Statut Membre 23
     

    Merci je viens de tester.

    Cela ajoute bien le E mais a tous les champs 'nal' alors qu'il faut ajouter ce E que pour els champ contenant une simple côte dans le nom et n'ajoute pas le \

    Voici le contenu du fichier a traiter :

    id_ace | ce  |  real  |      nal      
    ------------+-------+------------+--------------------
    172729759 |  3405 |         12 | 9 COSA D'ESE
    14981206 |  3316 | 23654980 | TERE D'ENL
    33157859 |  3654 |          5 | D LEVT
    1892720    |  2303 |         27 | L CONANT
    15432905 |  3335 |          2 | D'EMDE
    2425365 |  2836 |          7 | HP'LAUT !
    26330353 |  3612 |          1 | PAIS
    2425349 |  2832 | 28272083  | DE L'ARE

    Voici le résultat lorsque l'on joue la commande 

    awk -F " *[|] *" -v Q=\' '{s=$4; prov=($1~/^ *$/)?"":uid;printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, "E\x27" s "\x27")}' file.txt
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (172729759, 3405, 12, E'9 COSA D'ESE')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (14981206, 3316, 23654980, E'TERE D'ENL')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (33157859, 3654, 5, E'D LEVT')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (1892720, 2303, 27, E'L CONANT')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (15432905, 3335, 2, E'D'EMDE')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (2425365, 2836, 7, E'HP'LAUT !')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (26330353, 3612, 1, E'PAIS')
    INSERT INTO table (uid, co, ref_g, no_gl) VALUES (2425349, 2832, 28272083, E'DE L'ARE')
    

    Concernant mon fichier traité non il n'est pas séparé par des | et il s'intègre correctement dans ma BDD postgresql.


    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
       

      Nos réponses se sont croisées, j'ai oublié dans la première version l'instruction avec gsub que j'ai rajoutée ensuite. Donc, reprends mon message.#6 :

      awk -F \| '{s=$4; gsub("\x27", "\\\x27", s); printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, "E\x27" s "\x27")}' file.sql

      Ceci dit, maintenant que je vois ton fichier sql, j'ignorerais les 2 premières lignes à l'aide de tail et donc la commande devient :

      tail -n +3 file.sql | awk -F \| '{s=$4; gsub("\x27", "\\\x27", s); printf ("INSERT INTO table (uid, co, ref_g, no_gl) VALUES (%d, %s, %s, %s)\n", $1, $2, $3, "E\x27" s "\x27")}'

      Résultat :

      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (172729759,   3405 ,          12 , E' 9 COSA D\'ESE')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (14981206,   3316 ,  23654980 , E' TERE D\'ENL')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (33157859,   3654 ,           5 , E' D LEVT')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (1892720,   2303 ,          27 , E' L CONANT')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (15432905,   3335 ,           2 , E' D\'EMDE')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (2425365,   2836 ,           7 , E' HP\'LAUT !')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (26330353,   3612 ,           1 , E' PAIS')
      INSERT INTO table (uid, co, ref_g, no_gl) VALUES (2425349,   2832 ,  28272083  , E' DE L\'ARE')

      Ceci étant dit, reste toujours cette histoire de pg_dump en suspens...

      Bonne chance

      2
  8. pcsystemd Messages postés 734 Statut Membre 23
     

    Merci.


    0