Découper un fichier texte selon un motif répétitif
Résolu
Bonjour,
Je dispose d'un fichier texte de grande taille (1,2 Go) qui représente plusieurs centaines de tables d'une base de données Postgresl. J'aimerais le découper en autant de fichiers textes, un par table.
Chaque "segment" commence par trois lignes de type remarque préfixées "--". Ensuite le mot clé "COPY" suivi d'un espace, le nom de la table (qu'on pourrait utiliser pour nommer les fichiers de tables), suivent les données séparées par des CR/LF et termine par "\."
Voici un extrait (2 lignes de données) :
Pour être tout à fait clair, il s'agit d'un dump (sauvegarde) effectué avec le paramètre COPY au lieu du paramètre SQL. Suite à la migration, je dois reconstruire les tables en SQL mais ne dispose que de ce fichier. Dans l'idéal, il s'agirait de transformer les choses ainsi :
COPY a2_obje en INSERT INTO a2_obje
FROM stdin; en VALUES
puis d'encadrer chaque ligne de données par des parenthèses et séparer les valeurs par des virgules...
Mais tout cela est bien au-delà de mes compétences... :-(
Merci par avance et meilleurs messages
Didier
Je dispose d'un fichier texte de grande taille (1,2 Go) qui représente plusieurs centaines de tables d'une base de données Postgresl. J'aimerais le découper en autant de fichiers textes, un par table.
Chaque "segment" commence par trois lignes de type remarque préfixées "--". Ensuite le mot clé "COPY" suivi d'un espace, le nom de la table (qu'on pourrait utiliser pour nommer les fichiers de tables), suivent les données séparées par des CR/LF et termine par "\."
Voici un extrait (2 lignes de données) :
-- -- Data for Name: a2_obje; Type: TABLE DATA; Schema: accidents; Owner: dig -- COPY a2_obje (gemnr, objek, blatt, mang1, mang2, mang3, alkoh, anzpe, astaa, akate, fstaa, fkant, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, obj, but, col, prop, cond, perm, v36, v37, v38, per01, geb01, art01, sex01, sys01, fol01, tod01, per02, geb02, art02, sex02, sys02, fol02, tod02, per03, geb03, art03, sex03, sys03, fol03, tod03, per04, geb04, art04, sex04, sys04, fol04, tod04, katnr, permis, aseit) FROM stdin; 6621 1 1 170 423 0 0 1 CH C CH AG 215 244 262 270 280 286 000 000 000 000 000 215 244 \N 262 270 286 000 000 000 01 08051980 300 306 310 314 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 70022882 2002-03-28 28032002 6628 2 1 0 0 0 0 1 CH C CH GE 215 247 262 270 280 286 000 000 000 000 000 215 247 \N 262 270 286 000 000 000 01 30121961 300 306 310 314 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 100000614 1990-02-06 6021990 \.
Pour être tout à fait clair, il s'agit d'un dump (sauvegarde) effectué avec le paramètre COPY au lieu du paramètre SQL. Suite à la migration, je dois reconstruire les tables en SQL mais ne dispose que de ce fichier. Dans l'idéal, il s'agirait de transformer les choses ainsi :
COPY a2_obje en INSERT INTO a2_obje
FROM stdin; en VALUES
puis d'encadrer chaque ligne de données par des parenthèses et séparer les valeurs par des virgules...
Mais tout cela est bien au-delà de mes compétences... :-(
Merci par avance et meilleurs messages
Didier
A voir également:
- Découper un fichier texte selon un motif répétitif
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier bin - Guide
- Fichier rar - Guide
- Ouvrir un fichier .dat - Guide
9 réponses
hello
essayer
essayer
$ awk '/^--/ || /^$/ {next} /^COPY/ {f=$2; next} {print > f}' fichier $ cat a2_obje 6621 1 1 170 423 0 0 1 CH C CH AG 215 244 262 270 280 286 000 000 000 000 000 215 244 \N 262 270 286 000 000 000 01 08051980 300 306 310 314 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 70022882 2002-03-28 28032002 6628 2 1 0 0 0 0 1 CH C CH GE 215 247 262 270 280 286 000 000 000 000 000 215 247 \N 262 270 286 000 000 000 01 30121961 300 306 310 314 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 00 00000000 000 000 000 000 00000000 100000614 1990-02-06 6021990 \. $
J'ai beaucoup plus simple à te proposer. Pourquoi ne pas charger ces tables dans postgresql et ensuite dumper les tables une par une avec pg_dump, déjà ça réglerait le problème du découpage ?
Ensuite postgresql est tout à fait de charger un fichier csv.
https://stackoverflow.com/questions/2987433/how-to-import-csv-file-data-into-a-postgresql-table
Bonne chance
Ensuite postgresql est tout à fait de charger un fichier csv.
https://stackoverflow.com/questions/2987433/how-to-import-csv-file-data-into-a-postgresql-table
Bonne chance
Hello et merci pour ta réponse.
En fait, mon post était déjà assez long et je ne voulais pas surcharger. Le fichier en question provient déjà d'un pg_dump et ce sont des tables PostGIS (pas celle de l'exemple). En plus, il y a plusieurs centaines de tables... Je me vois mal passer un pg_dump pour chacune.
Et la raison de mon post est l'impossibilité de passer un pg_restore ! Il plante systématiquement
Merci encore pour l'intérêt.
En fait, mon post était déjà assez long et je ne voulais pas surcharger. Le fichier en question provient déjà d'un pg_dump et ce sont des tables PostGIS (pas celle de l'exemple). En plus, il y a plusieurs centaines de tables... Je me vois mal passer un pg_dump pour chacune.
Et la raison de mon post est l'impossibilité de passer un pg_restore ! Il plante systématiquement
Merci encore pour l'intérêt.
Dans l'absolu le nombre de table n'est pas un problème, car il est possible d'écrire une fonction en pgsql pour itérer sur chaque table. Tu peux par exemple écrire le fichier suivant (dump.sql) ou copier ce qui suit dans ton interpréteur pgsql :
Pour charger dump.sql :
Ensuite, je ne comprends pas pourquoi utiliser pg_restore (et sans message d'erreur difficile de dire pourquoi il plante). Pour moi, tu peux charger ce fichier en lançant :
Il suffit ensuite de lancer la fonction :
Bonne chance
CREATE OR REPLACE FUNCTION dump() RETURNS void AS $$ DECLARE v_filename text; v_query text; v_table_name text; v_latest_name text; v_master_id integer; BEGIN FOR v_table_name IN SELECT c.relname AS "Name" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY c.relname ASC LOOP v_filename = '/tmp/' || v_table_name || '.csv'; v_query = 'COPY (SELECT * FROM ' || v_table_name || ') TO ' quote_literal(v_filename) ' WITH CSV HEADER '; RAISE NOTICE 'Query: %', v_query; EXECUTE v_query; END LOOP; END $$ LANGUAGE plpgsql;
Pour charger dump.sql :
psql -U postgres -d monschema < dump.sql
Ensuite, je ne comprends pas pourquoi utiliser pg_restore (et sans message d'erreur difficile de dire pourquoi il plante). Pour moi, tu peux charger ce fichier en lançant :
psql -U postgres -d monschema < monfichier.sql
Il suffit ensuite de lancer la fonction :
psql -U postgres -d monschema select dump();
Bonne chance
Re-Salut et Merci d'insister car je pense que tu as la connaissance qui devrait m'aider à me tirer d'affaire... je suis un peu désespéré...
Je prépare une réponse plus complète avec explications détaillées et messages d'erreur que je posterai demain matin.
Merci par avance pour ton aide
Didier
Je prépare une réponse plus complète avec explications détaillées et messages d'erreur que je posterai demain matin.
Merci par avance pour ton aide
Didier
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
@mamiemando,
Je reviens avec plus de détails.
Je suis géographe et j'utilise postgresql-postgis sur un serveur récupéré (non répliqué) mis à dispo par le service informatique de mon entreprise.
Nos informaticiens ont fait une migration dudit serveur sous Debian, postgres 8.3 vers 8.4 et postgis 1.3.3 vers ???. Tout à bien passé... faut le dire vite... sauf la remontée des données... Voilà pour le décorum !
J'avais préalablement fait une sauvegarde de la bdd depuis phppgadmin avec l'option COPY (j'aurais dû faire SQL). C'est le fichier dont je parle à l'origine de ce post, un dump.sql de 1.2 Go.
Nous avons suivi les procédures décrites par postgis, à savoir recréer une nouvelle base de donnée, lui adjoindre les fonctions spatiales etc.
C'est au moment de vouloir utiliser le fichier dump.sql avec psql que tout s'est gâté !
Nous avons rencontrés rapidement des erreurs : commande invalide \N...
En découpant le dump, j'ai pu supprimer la partie créant les fonctions spatiales et isoler la partie création des tables et vues : OK !
Il ne reste(rait) plus qu'à remonter les données... :-(
Le fichier dump.sql s'arrête inexorablement avec cette erreur au sujet des \N!
C'est pourquoi, je tente de recréer le fichier en SQL avec des INSERT INTO au lieu du COPY ... FROM stdin;
Voilà l'état de la chose !
Je reviens avec plus de détails.
Je suis géographe et j'utilise postgresql-postgis sur un serveur récupéré (non répliqué) mis à dispo par le service informatique de mon entreprise.
Nos informaticiens ont fait une migration dudit serveur sous Debian, postgres 8.3 vers 8.4 et postgis 1.3.3 vers ???. Tout à bien passé... faut le dire vite... sauf la remontée des données... Voilà pour le décorum !
J'avais préalablement fait une sauvegarde de la bdd depuis phppgadmin avec l'option COPY (j'aurais dû faire SQL). C'est le fichier dont je parle à l'origine de ce post, un dump.sql de 1.2 Go.
Nous avons suivi les procédures décrites par postgis, à savoir recréer une nouvelle base de donnée, lui adjoindre les fonctions spatiales etc.
C'est au moment de vouloir utiliser le fichier dump.sql avec psql que tout s'est gâté !
Nous avons rencontrés rapidement des erreurs : commande invalide \N...
En découpant le dump, j'ai pu supprimer la partie créant les fonctions spatiales et isoler la partie création des tables et vues : OK !
Il ne reste(rait) plus qu'à remonter les données... :-(
Le fichier dump.sql s'arrête inexorablement avec cette erreur au sujet des \N!
C'est pourquoi, je tente de recréer le fichier en SQL avec des INSERT INTO au lieu du COPY ... FROM stdin;
Voilà l'état de la chose !
et comme ça
$ awk '/^--/ || !NF {next} /^COPY/ {f=$2; $0="INSERT INTO " f " VALUES (" } {sub("\\\\\.$", ")"); gsub("\t", ";"); print > f}' fichier awk: warning: escape sequence '\.' treated as plain '.' $ more a2_obje INSERT INTO a2_obje VALUES ( 6621;1;1;170;423;0;0;1;CH ;C ;CH ;AG;215;244;262;270;280;286;000;000;000;000;000;215;244;\N;262;270;286;000;000;000;01;08051980;300;306;310;314;00000000;00;0 0000000;000;000;000;000;00000000;00;00000000;000;000;000;000;00000000;00;00000000;000;000;000;000;00000000;70022882;2002-03-28;28032002 6628;2;1;0;0;0;0;1;CH ;C ;CH ;GE;215;247;262;270;280;286;000;000;000;000;000;215;247;\N;262;270;286;000;000;000;01;30121961;300;306;310;314;00000000;00;00000 000;000;000;000;000;00000000;00;00000000;000;000;000;000;00000000;00;00000000;000;000;000;000;00000000;100000614;1990-02-06;6021990 ) $ $
J'avais préalablement fait une sauvegarde de la bdd depuis phppgadmin avec l'option COPY (j'aurais dû faire SQL). C'est le fichier dont je parle à l'origine de ce post, un dump.sql de 1.2 Go.
Je pense que ça ne change pas grand chose car phppgadmin va a priori lancer pg_dump en arrière boutique, donc le résultat aurait été le même.
Nous avons suivi les procédures décrites par postgis, à savoir recréer une nouvelle base de donnée, lui adjoindre les fonctions spatiales etc.
C'est au moment de vouloir utiliser le fichier dump.sql avec psql que tout s'est gâté !
Nous avons rencontrés rapidement des erreurs : commande invalide \N...
Encore une fois, as-tu simplement essayé de charger le dump original avec une commande du genre :
As-tu essayé avec pg_restore (ou via phpphadmin) de restaurer ton dump ?
Le fichier dump.sql s'arrête inexorablement avec cette erreur au sujet des \N! C'est pourquoi, je tente de recréer le fichier en SQL avec des INSERT INTO au lieu du COPY ... FROM stdin;
Quel est le message d'erreur exact ? Car à mon avis tu n'es pas la première personne qui aurait pu rencontrer le problème.
Ensuite une question qu'on peut se poser c'est si tu as vraiment besoin d'héberger un serveur de carte chez toi) quand il existe des serveurs de carte publics comme google.maps (ou même des projets libres comme openstreetmap, mapserver)...
Bonne chance
Je pense que ça ne change pas grand chose car phppgadmin va a priori lancer pg_dump en arrière boutique, donc le résultat aurait été le même.
Nous avons suivi les procédures décrites par postgis, à savoir recréer une nouvelle base de donnée, lui adjoindre les fonctions spatiales etc.
C'est au moment de vouloir utiliser le fichier dump.sql avec psql que tout s'est gâté !
Nous avons rencontrés rapidement des erreurs : commande invalide \N...
Encore une fois, as-tu simplement essayé de charger le dump original avec une commande du genre :
psql -U postgres -d monschema < monfichier.sql
As-tu essayé avec pg_restore (ou via phpphadmin) de restaurer ton dump ?
Le fichier dump.sql s'arrête inexorablement avec cette erreur au sujet des \N! C'est pourquoi, je tente de recréer le fichier en SQL avec des INSERT INTO au lieu du COPY ... FROM stdin;
Quel est le message d'erreur exact ? Car à mon avis tu n'es pas la première personne qui aurait pu rencontrer le problème.
Ensuite une question qu'on peut se poser c'est si tu as vraiment besoin d'héberger un serveur de carte chez toi) quand il existe des serveurs de carte publics comme google.maps (ou même des projets libres comme openstreetmap, mapserver)...
Bonne chance
Hello,
Oui aux deux première questions (psql -U postgres... et pg_restore...)
Le message d'erreur est laconiquement : commande invalide \N et nous avons trouvé effectivement des questions à ce sujet sur le Net... malheureusement sans réponse utile pour nous !.
Pour ton dernier paragraphe??? J'utilise OSM et Mapserver pour créer des WMS avec les données contenues dans les tables POSTGIS. Je transforme parfois ces tables en GeoJson. Je n'utilise pas Gmaps car l'API est trop restrictif en matière de licences (mes cartes sont visibles uniquement en Intranet) qui oblige la visibilité depuis Internet et je privilégie OpenLayers...
Pour couronner le tout, je reçois du SITG (système d'information du territoire genevois http:/www.sitg.ch) de nombreuses couches de références vectorielles en shapes que je remonte de PostGis... Voilà voilà. De ce côté ça va.
1000 mercis pour ton aide et ton intérêt à mes questions.
Amitiés
Didier
Oui aux deux première questions (psql -U postgres... et pg_restore...)
Le message d'erreur est laconiquement : commande invalide \N et nous avons trouvé effectivement des questions à ce sujet sur le Net... malheureusement sans réponse utile pour nous !.
Pour ton dernier paragraphe??? J'utilise OSM et Mapserver pour créer des WMS avec les données contenues dans les tables POSTGIS. Je transforme parfois ces tables en GeoJson. Je n'utilise pas Gmaps car l'API est trop restrictif en matière de licences (mes cartes sont visibles uniquement en Intranet) qui oblige la visibilité depuis Internet et je privilégie OpenLayers...
Pour couronner le tout, je reçois du SITG (système d'information du territoire genevois http:/www.sitg.ch) de nombreuses couches de références vectorielles en shapes que je remonte de PostGis... Voilà voilà. De ce côté ça va.
1000 mercis pour ton aide et ton intérêt à mes questions.
Amitiés
Didier
Encore une fois, as-tu simplement essayé de charger le dump original avec une commande du genre :
psql -U postgres -d monschema < monfichier.sql
psql -U postgres -d monschema < monfichier.sql
\N désigne la valeur NULL. Il me faudrait un extrait minimal du dump qui illustre le problème (dans l'idée, le CREATE TABLE de la table sur laquelle il y a l'erreur et le COPY ou le INSERT qui échoue).
Sans ça c'est difficile de comprendre d'où vient le problème.
Sans ça c'est difficile de comprendre d'où vient le problème.
Oups ! Sorry !
En fait, il y avait un extrait (qui provoque l'erreur également) dans mon post d'origine ! ;-)
D'autre part, nous avons enfin pu reconstruire les tables les plus vitales grâce aux découpages de dubcek, que je remercie encore une fois au passage.
Et un grand MERCI à toi aussi mamiemando pour l'intérêt que tu as mobilisé pour m'aider et les indications que tu nous as données pour nous y retrouver.
Je vais clore ce post par un résolu.
En fait, il y avait un extrait (qui provoque l'erreur également) dans mon post d'origine ! ;-)
D'autre part, nous avons enfin pu reconstruire les tables les plus vitales grâce aux découpages de dubcek, que je remercie encore une fois au passage.
Et un grand MERCI à toi aussi mamiemando pour l'intérêt que tu as mobilisé pour m'aider et les indications que tu nous as données pour nous y retrouver.
Je vais clore ce post par un résolu.
Merci beaucoup !!!
Je vais tenter des modifications en amont et m'inspirer de ce code pour générer les 221 tables à savoir :
- remplacer le COPY par INSERT INTO avec un sed;
- remplacer le FROM stdin; par VALUES (;
-remplacer le \. par un )
-remplacer les tabulations par des points-virgules.
Et hop, du coup je devrais avoir mes requêtes SQL prêtes pour réintroduire mes données !!!
Encore 1000 mercis à dubcek !