Insérer un séparateur dans un fichier texte

Insérer un séparateur dans un fichier texte - Divers - Programmation

Marsh Posté le 11-07-2014 à 07:55:10    

Bonjour,

 

J'ai un fichier texte d'environ 40 millions de lignes pour 1 Go.
Je l'analyse avec R
C'est un fichier qui contient pour chaque ligne une suite de chiffres.
J'ai le codebook qui m'indique les espaces délimités (par exemple les 2 premiers chiffres correspondent à la variable 1, les 3 chiffres suivant à la variable 2)
Pour l'importer et l'utiliser j'ai donc besoin de le convertir en csv ou équivalent.

 

De ce que j'ai vu, le plus pratique pour ca c'est awk, mais je n'ai pas trouvé de syntaxe pour indiquer nominalement à quel endroit il faut introduire le séparateur dans le fichier ...
Si vous avez une astuce pour ces méthodes je suis preneur :jap:

Message cité 1 fois
Message édité par Magicpanda le 11-07-2014 à 09:00:09

---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 11-07-2014 à 07:55:10   

Reply

Marsh Posté le 11-07-2014 à 09:57:45    

Bon j'ai trouvé une procédure avec Stata, mais j'ai des soucis dans le dictionnaire, il reste des blancs dans le fichier texte qui décalent les colonnes qu'il faut que je supprime ...


---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 11-07-2014 à 11:02:29    

Bonjour,
Si tu donnes un exemple de ligne en entrée et de ligne souhaitée en sortie, je t'écris le code Perl correspondant.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-07-2014 à 13:00:33    

:hello: !
 

Magicpanda a écrit :

Bonjour,  
 
J'ai un fichier texte d'environ 40 millions de lignes pour 1 Go.
Je l'analyse avec R  
C'est un fichier qui contient pour chaque ligne une suite de chiffres.
J'ai le codebook qui m'indique les espaces délimités (par exemple les 2 premiers chiffres correspondent à la variable 1, les 3 chiffres suivant à la variable 2)
Pour l'importer et l'utiliser j'ai donc besoin de le convertir en csv ou équivalent.
 
De ce que j'ai vu, le plus pratique pour ca c'est awk, mais je n'ai pas trouvé de syntaxe pour indiquer nominalement à quel endroit il faut introduire le séparateur dans le fichier ...
Si vous avez une astuce pour ces méthodes je suis preneur :jap:


Tu veux dire quoi par "les espaces délimités" ? :??: C'est le format de ton fichier, ou tes valeurs sont séparées par des espaces ?
Si tu le fais en shell, tu peux peut-être utiliser la syntaxe ${string:position:length} pour extraire une partie d'une chaîne de caractères.
 
:jap:
 
Edit : Voici un petit exemple [:cupra]

Code :
  1. export test=aabbbcccdddd
  2. echo ${test:0:2} ${test:2:3} ${test:5:3} ${test:8:4}


Message édité par Soileh le 11-07-2014 à 13:08:05

---------------
And in the end, the love you take is equal to the love you make
Reply

Marsh Posté le 11-07-2014 à 14:52:07    

quand je dis espace délimité, j'ai une suite de chiffres genre

 

45456465489879871213213548979843415321356

 

et j'ai un codebook a coté qui me dit

 

premier variable : 2 premières valeurs
deuxieme : 3 suivants
etc ..

 

J'ai trouvé une syntaxe d'importation qui fonctionne pour SPSS je pense que c'est bon :jap: merci !
j'ai effectivement trouvé des tutos pour le faire en python et en perl, il faudra que je m'y penche, d'habitude je le fais avec R mais là le fichier est trop gros pour être digéré !


Message édité par Magicpanda le 11-07-2014 à 14:53:23

---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 11-07-2014 à 15:13:58    

ma syntaxe sps


 
GET DATA
   /TYPE=TXT
   /FILE='C:\Users\Antoine\Desktop\DATASET\Microdatos.txt'
   /FIXCASE=1
   /ARRANGEMENT=FIXED
   /FIRSTCASE=1
   /IMPORTCASE=ALL
   /VARIABLES=
   /1 V1 0-1 F2.0
   V2 2-4 F3.0
   V3 5-14 F10.0
   V4 15-18 F4.0
   V5 19-32 F14.1
   V6 33-34 F2.0
   V7 35-38 F4.0
   V8 39-41 F3.0
   V9 42-42 F1.0
   V10 43-45 F3.0
   V11 46-48 F3.0
   V12 49-50 A2
   V13 51-53 A3
   V14 54-57 F4.0
   V15 58-61 F4.0
   V16 62-65 F4.0
   V17 66-69 F4.0
   V18 70-72 F3.0
   V19 73-74 F2.0
   V20 75-77 F3.0
   V21 78-80 F3.0
   V22 81-82 F2.0
   V23 83-85 F3.0
   V24 86-88 A3
   V25 89-90 A2
   V26 91-93 A3
   V27 94-94 F1.0
   V28 95-97 A3
   V29 98-99 A2
   V30 100-102 A3
   V31 103-105 A3
   V32 106-106 A1
   V33 107-107 F1.0
   V34 108-108 A1
   V35 109-111 A3
   V36 112-112 A1
   V37 113-113 A1
   V38 114-114 A1
   V39 115-115 A1
   V40 116-116 A1
   V41 117-118 A2
   V42 119-119 A1
   V43 120-120 A1
   V44 121-122 A2
   V45 123-124 A2
   V46 125-125 A1
   V47 126-127 A2
   V48 128-129 A2
   V49 130-131 A2
   V50 132-132 A1
   V51 133-135 A3
   V52 136-137 A2
   V53 138-140 A3
   V54 141-145 A5
   V55 146-146 A1
   V56 147-147 A1
   V57 148-148 A1
   V58 149-149 A1
   V59 150-150 F1.0
   V60 151-151 F1.0
   V61 152-152 F1.0
   V62 153-153 F1.0
   V63 154-154 F1.0
   V64 155-155 F1.0
   V65 156-158 F3.0
   V66 159-160 F2.0
   V67 161-162 A2
   V68 163-163 A1
   V69 164-164 A1
   V70 165-166 A2
   V71 167-167 A1
   V72 168-168 A1
   V73 169-169 A1
   V74 170-170 A1
   V75 171-171 A1
   V76 172-172 A1
   V77 173-173 A1
   V78 174-174 A1
   V79 175-175 A1
   V80 176-176 F1.0
   V81 177-178 A2
   V82 179-180 A2
   V83 181-182 A2
   V84 183-184 A2
   V85 185-185 A1
   V86 186-187 F2.0
   V87 188-189 F2.0
   V88 190-190 F1.0
   V89 191-191 F1.0
   V90 192-193 F2.0
   V91 194-195 F2.0
   V92 196-197 F2.0
   V93 198-199 F2.0
   V94 200-201 F2.0
   V95 202-203 F2.0
   V96 204-205 F2.0
   V97 206-207 F2.0
   V98 208-209 F2.0
   V99 210-211 F2.0
   V100 212-213 F2.0
   V101 214-215 F2.0
   V102 216-217 F2.0
   V103 218-219 F2.0
   V104 220-221 F2.0
   V105 222-223 F2.0
   V106 224-225 F2.0
   V107 226-227 F2.0
   V108 228-228 F1.0
   V109 229-230 A2
   V110 231-233 F3.0
   V111 234-234 A1
   V112 235-235 A1
   V113 236-236 A1
   V114 237-237 A1
   V115 238-238 A1
   V116 239-240 A2
   V117 241-243 F3.0
   V118 244-244 A1
   V119 245-245 A1
   V120 246-246 A1
   V121 247-247 A1
   V122 248-248 A1
   V123 249-250 A2
   V124 251-251 A1
   V125 252-252 A1
   V126 253-253 A1
   V127 254-254 A1
   V128 255-255 A1
   V129 256-256 A1
   V130 257-257 A1
   V131 258-259 A2
   V132 260-261 A2
   V133 262-263 A2
   V134 264-265 A2
   V135 266-267 A2
   V136 268-269 A2
   V137 270-271 A2
   V138 271-272 F1.0.
 
 CACHE.
 EXECUTE.



---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 11-07-2014 à 18:37:26    

Citation :

V137 270-271 A2
V138 271-272 F1.0.

Il y a une erreur a la dernière ligne: ce devrait être V138 272-272 F1.0. non?
 
A+,


Message édité par gilou le 11-07-2014 à 18:37:49

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-07-2014 à 19:40:47    

Voici un truc en perl cablé sur ton format (avec un peu d'effort, on pourrait en faire un truc générique).
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. ### Recuperation du format
  7. ### Et vérification de la consistence
  8.  
  9. # Format après copier-coller
  10. my $format = <<"ENDFORMAT";
  11.   V1 0-1 F2.0
  12.   V2 2-4 F3.0
  13.   V3 5-14 F10.0
  14.   V4 15-18 F4.0
  15.   V5 19-32 F14.1
  16.   V6 33-34 F2.0
  17.   V7 35-38 F4.0
  18.   V8 39-41 F3.0
  19.   V9 42-42 F1.0
  20.   V10 43-45 F3.0
  21.   V11 46-48 F3.0
  22.   V12 49-50 A2
  23.   V13 51-53 A3
  24.   V14 54-57 F4.0
  25.   V15 58-61 F4.0
  26.   V16 62-65 F4.0
  27.   V17 66-69 F4.0
  28.   V18 70-72 F3.0
  29.   V19 73-74 F2.0
  30.   V20 75-77 F3.0
  31.   V21 78-80 F3.0
  32.   V22 81-82 F2.0
  33.   V23 83-85 F3.0
  34.   V24 86-88 A3
  35.   V25 89-90 A2
  36.   V26 91-93 A3
  37.   V27 94-94 F1.0
  38.   V28 95-97 A3
  39.   V29 98-99 A2
  40.   V30 100-102 A3
  41.   V31 103-105 A3
  42.   V32 106-106 A1
  43.   V33 107-107 F1.0
  44.   V34 108-108 A1
  45.   V35 109-111 A3
  46.   V36 112-112 A1
  47.   V37 113-113 A1
  48.   V38 114-114 A1
  49.   V39 115-115 A1
  50.   V40 116-116 A1
  51.   V41 117-118 A2
  52.   V42 119-119 A1
  53.   V43 120-120 A1
  54.   V44 121-122 A2
  55.   V45 123-124 A2
  56.   V46 125-125 A1
  57.   V47 126-127 A2
  58.   V48 128-129 A2
  59.   V49 130-131 A2
  60.   V50 132-132 A1
  61.   V51 133-135 A3
  62.   V52 136-137 A2
  63.   V53 138-140 A3
  64.   V54 141-145 A5
  65.   V55 146-146 A1
  66.   V56 147-147 A1
  67.   V57 148-148 A1
  68.   V58 149-149 A1
  69.   V59 150-150 F1.0
  70.   V60 151-151 F1.0
  71.   V61 152-152 F1.0
  72.   V62 153-153 F1.0
  73.   V63 154-154 F1.0
  74.   V64 155-155 F1.0
  75.   V65 156-158 F3.0
  76.   V66 159-160 F2.0
  77.   V67 161-162 A2
  78.   V68 163-163 A1
  79.   V69 164-164 A1
  80.   V70 165-166 A2
  81.   V71 167-167 A1
  82.   V72 168-168 A1
  83.   V73 169-169 A1
  84.   V74 170-170 A1
  85.   V75 171-171 A1
  86.   V76 172-172 A1
  87.   V77 173-173 A1
  88.   V78 174-174 A1
  89.   V79 175-175 A1
  90.   V80 176-176 F1.0
  91.   V81 177-178 A2
  92.   V82 179-180 A2
  93.   V83 181-182 A2
  94.   V84 183-184 A2
  95.   V85 185-185 A1
  96.   V86 186-187 F2.0
  97.   V87 188-189 F2.0
  98.   V88 190-190 F1.0
  99.   V89 191-191 F1.0
  100.   V90 192-193 F2.0
  101.   V91 194-195 F2.0
  102.   V92 196-197 F2.0
  103.   V93 198-199 F2.0
  104.   V94 200-201 F2.0
  105.   V95 202-203 F2.0
  106.   V96 204-205 F2.0
  107.   V97 206-207 F2.0
  108.   V98 208-209 F2.0
  109.   V99 210-211 F2.0
  110.   V100 212-213 F2.0
  111.   V101 214-215 F2.0
  112.   V102 216-217 F2.0
  113.   V103 218-219 F2.0
  114.   V104 220-221 F2.0
  115.   V105 222-223 F2.0
  116.   V106 224-225 F2.0
  117.   V107 226-227 F2.0
  118.   V108 228-228 F1.0
  119.   V109 229-230 A2
  120.   V110 231-233 F3.0
  121.   V111 234-234 A1
  122.   V112 235-235 A1
  123.   V113 236-236 A1
  124.   V114 237-237 A1
  125.   V115 238-238 A1
  126.   V116 239-240 A2
  127.   V117 241-243 F3.0
  128.   V118 244-244 A1
  129.   V119 245-245 A1
  130.   V120 246-246 A1
  131.   V121 247-247 A1
  132.   V122 248-248 A1
  133.   V123 249-250 A2
  134.   V124 251-251 A1
  135.   V125 252-252 A1
  136.   V126 253-253 A1
  137.   V127 254-254 A1
  138.   V128 255-255 A1
  139.   V129 256-256 A1
  140.   V130 257-257 A1
  141.   V131 258-259 A2
  142.   V132 260-261 A2
  143.   V133 262-263 A2
  144.   V134 264-265 A2
  145.   V135 266-267 A2
  146.   V136 268-269 A2
  147.   V137 270-271 A2
  148.   V138 272-272 F1.0
  149. ENDFORMAT
  150.  
  151. my %var;
  152. foreach (split /\n/, $format) {
  153.  if (/^\s*V(\d+)\s+(\d+)-(\d+)\s+A(\d+)\s*$/) {
  154.    $var{$1}{type} = "A";
  155.    $var{$1}{first} = $2;
  156.    $var{$1}{last} = $3;
  157.    $var{$1}{size} = $4;
  158.    if ($3-$2+1 != $4) {
  159.      die "Inconsistency in format size $_\n";
  160.    }
  161.  }
  162.  elsif (/^\s*V(\d+)\s+(\d+)-(\d+)\s+F(\d+)\.(\d+)\s*$/) {
  163.    $var{$1}{type} = "F";
  164.    $var{$1}{first} = $2;
  165.    $var{$1}{last} = $3;
  166.    $var{$1}{size} = $4;
  167.    $var{$1}{comma} = $5;
  168.    if (($3-$2+1 != $4) || ($5 > $4)) {  # ou $5 >= $4 ??
  169.      die "Inconsistency in format size $_\n";
  170.    }
  171.  }
  172.  else {
  173.    die "ligne format erronee $_!\n";
  174.  }
  175. }
  176.  
  177. # On vérifie qu'il y a pas de trous
  178. my $current = 0;
  179. foreach (sort { $a <=> $b } keys %var) {
  180.  if ($current != $var{$_}{first}) {
  181.    die "Gap in data at var $_\n";
  182.  }
  183.  $current = $var{$_}{last} + 1;
  184. }
  185.  
  186. ### creation du parametre associé pour la fonction unpack
  187. my $packformat = "";
  188. foreach (sort { $a <=> $b } keys %var) {
  189.  $packformat .= "A$var{$_}{size}";
  190. }
  191.  
  192. ### préliminaires terminés
  193. ### lecture ligne a ligne du fichier source
  194. ### une ligne est découpée selon le format $packformat,
  195. ### les morceaux sont joints avec un ; entre chaque morceau
  196. ### et le résultat est écrit en sortie
  197. open my $infile, "<", "infilename";
  198. open my $outfile, ">", "outfilename";
  199. while (<$infile> ) {
  200.  chop;
  201.  if ( $current > length($_)) {
  202.    print "line too short in data source, end of file skipped\n";
  203.    last;
  204.  }
  205.  print $outfile join(';', unpack($packformat, $_)), "\n";
  206. }
  207. close $outfile;
  208. close $infile;


 
il reste le cas de ta 5e variable, la seule F a ne pas être en .0
  V5 19-32 F14.1
Faut il réintégrer le point décimal? et si oui, F14.1, c'est 1 chiffre avant et 13 après?
Si oui,  en remplaçant à la fin
  print $outfile join(';', unpack($packformat, $_)), "\n";
par
  my $line = join(';', unpack($packformat, $_));
  print $outfile substr($line, 0, 24), ".", substr($line, 24), "\n";
ça devrait baigner.
 
Bon par contre si les F en .0 doivent être écrits avec un 0. ou un . devant, c'est faisable, mais juste un poil plus compliqué (et un peu plus lent aussi, car il faudra faire une boucle sur keys %var pour chaque ligne lue).
 
A+,


Message édité par gilou le 11-07-2014 à 21:18:04

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-07-2014 à 23:28:33    

Merci beaucoup Gilou, effectivement il y avait une coquille dans la derniere ligne !
revanche le f14.1 reste, c'est la nomenclature du recensement espagnol ;-)
f14.1 je ne sais pas pourquoi SPSS le code comme ca, mais c'est 3 chiffres, puis une décimale et 11 autres.
les F.0 sont des entiers en fait ;-) mais par défaut j'ai demandé à spss de prendre des flottants pour pas avoir a gérer de cas particuliers :jap:


---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 12-07-2014 à 02:43:45    

> f14.1 je ne sais pas pourquoi SPSS le code comme ca, mais c'est 3 chiffres, puis une décimale et 11 autres.  
Dans ce cas la, c'est  
my $line = join(';', unpack($packformat, $_));  
print $outfile substr($line, 0, 26), ".", substr($line, 26), "\n";  
si tu veux faire apparaitre le point entre les 3 premiers chiffres et les 11 autres.
ou mon code initial
print $outfile join(';', unpack($packformat, $_)), "\n";
si pas de point et juste la suite des 14 chiffres figurant entre les positions 19 et 32
 
A+,


Message édité par gilou le 12-07-2014 à 02:46:30

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-07-2014 à 02:43:45   

Reply

Marsh Posté le 12-07-2014 à 03:30:49    

Magicpanda a écrit :

f14.1 je ne sais pas pourquoi SPSS le code comme ca, mais c'est 3 chiffres, puis une décimale et 11 autres.


Euh non.
J'ai la doc SPSS 12.0 Command Syntax Reference sous les yeux.
Pour du Fixed-Format Data, ce qui est ton cas, il est dit:

Citation :

If a value has no coded decimal point but the input format specifies decimal positions, the
rightmost positions are interpreted as implied decimal digits. For example, if the input F
format specifies two decimal digits, the value 1234 is interpreted as 12.34; however, the
value 123.4 is still interpreted as 123.4.


Donc s'il n'y a pas de point dans tes datas mais uniquement des chiffres, f14.1,c'est un champ de 14 chiffres, et ça correspond a 13 chiffres avant la décimale et un après.
C'est d'ailleurs cohérent avec la notation Fn.0 tous les n chiffres sont avant la décimale (car il y en a 0 après), on adonc un entier.
3 chiffres, puis une décimale et 11 autres, c'est F14.11 selon cette doc.
 
A+,


Message édité par gilou le 12-07-2014 à 03:36:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 12-07-2014 à 19:21:28    

Effectivement c'est étrange, je vais vérifier dans le fichier de données pour voir le résultat


---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 12-07-2014 à 19:25:30    

Assez étrangement, les variables F sont en fait des entiers, sauf la V5
la V5 a bien une décimale, mais c'est 1 avant et 13 après le séprateur. Donc il y a  bien un soucis quelque part, il faut que je clean le dico en regardant la doc du fichier


---------------
" Quel est le but du capital ? Le but du capital c'est produire pour le capital. L'objectif, lui, est illimité. L'objectif du capital c'est produire pour produire." - Deleuze || André Gorz - Vers la société libérée
Reply

Marsh Posté le 12-07-2014 à 22:37:24    

Magicpanda a écrit :

Assez étrangement, les variables F sont en fait des entiers, sauf la V5
la V5 a bien une décimale, mais c'est 1 avant et 13 après le séprateur. Donc il y a  bien un soucis quelque part, il faut que je clean le dico en regardant la doc du fichier

Donc quelqu'un a pensé que ça correspondait à F14.1 alors que cela correspond a F14.13
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed