Résultats commande AWK

Résolu

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. Modérateur

    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. Contributeur

      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. 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..


        1. Modérateur

          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

          1. 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 ?


            1. Modérateur

              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

          2. 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.


            1. Modérateur

              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