Convertir un fichier de longueur fixe en fichier csv

Comment puis-je :

  1. Convertir un fichier de longueur fixe en fichier csv.

  2. Fractionner les enregistrements du fichier d’entrée (fichier de longueur fixe) selon la longueur de la colonne.

J’ai essayé de convertir le fichier en utilisant awk‘, cependant, le résultat est incorrect en raison des espaces dans les enregistrements.

Fichier d’entrée:

4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 00409164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 004009164 4002000W1ABCDABCD7821 12345671LSN12301630 00000000000091640 004009164 

Le premier enregistrement commence à 4002000W1ABCDABCD7821 et se termine à 00409164

Il y a 6 enregistrements au total.

Le fichier d’entrée contient 6 enregistrements pour la table.

Il y a plus de 40 colonnes dans le dossier, je n’en ai mentionné que quelques-unes.

Les colonnes ont une longueur fixe comme suit:

 ABC_ID(9), def_sc(8), sde_hd(8),mln_hfg(12), ghi_jkl(13),ijk_klm(6),pqr_xyz(10) 

Le résultat attendu est le suivant:

Fichier de sortie:

 ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 4002000W1, ABCDABCD,78211234, 56702291LSN1, 2301630000000, 000916, 4000409164 

Est-ce possible d’obtenir en utilisant la commande sed.

Veuillez suggérer.

Ce que vous voulez n’est pas tout à fait clair, mais GNU awk pour FIELDWIDTHS et RS multi-char est une option:

 $ awk -v RS='^$' -v FIELDWIDTHS="9 8 8 8" -v OFS=', ' '{gsub(/\n/,""); print $1, $2, $3, $4}' file 4002000W1, ABCDABCD, 78211234, 56789071 
 awk -v FIELDWIDTHS="9 8 8 12 13 6 10" 'NR%2{temp=$0;next;} {$0=temp$0; gsub(/ /,""); print $1,$2,$3,$4,$5,$6,$7}' OFS=',' file 

Fichier d’entrée:

 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 4002000W1ABCDABCD7821 123456702291LSN1230 16300000000009164 000409164 

Fichier de sortie:

 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 4002000W1,ABCDABCD,78211234,56702291LSN1,2301630000000,000916,4000409164 

Pour append la première ligne, imprimez-la tout d’abord dans BEGIN{...} :

 awk -v FIELDWIDTHS="9 8 8 12 13 6 10" 'BEGIN{print "ABC_ID, def_sc, sde_hd, mln_hfg, ghi_jkl, ijk_klm, pqr_xyz"} NR%2{temp=$0;next;} {$0=temp$0; gsub(/ /,""); print $1,$2,$3,$4,$5,$6,$7}' OFS=',' file 

Explication:

  • FIELDWIDTHS="9 8 8 12 13 6 10" spécifie la longueur des champs à imprimer.
  • NR%2{temp=$0;next;} stocke une ligne impaire dans la variable temp (sera utilisée pour joindre la paire de lignes)
  • $0=temp$0 rejoint chaque ligne consécutive. $0 est la ligne courante et la temp est la ligne avant la ligne courante.
  • gsub(/ /,""); supprime les caractères d’espace.
  • print $1,$2,$3,$4,$5,$6,$7 imprime les sept champs avec des largeurs prédéfinies par FIELDWIDTHS

Voici une solution Perl:

 use ssortingct; use warnings; my @fmt = (9, 8, 8, 12, 13, 6, 10); my @head = qw(ABC_ID def_sc sde_hd mln_hfg ghi_jkl ijk_klm pqr_xyz); my $rec_len = do { my $sum; for(@fmt) { $sum += $_ }; $sum }; my $fn = 'file'; open(my $fh, '<', $fn) or die "Could not open file '$fn': $!\n"; my $str = do {local $/ = undef; <$fh>}; close($fh); $str =~ s/\s*//g; my $regex = join ("", map { "(.{$_})" } @fmt); my $head_fmt = join (", ", map { "%-". $_ . "s", } @fmt) . "\n"; printf $head_fmt, @head; while ( $str =~ /(.{$rec_len})/g ) { my @f = $1 =~ /$regex/; print join(", ", @f) . "\n"; } 

Sortie:

 ABC_ID , def_sc , sde_hd , mln_hfg , ghi_jkl , ijk_klm, pqr_xyz 4002000W1, ABCDABCD, 78211234, 5671LSN12301, 6300000000000, 009164, 0004091644 002000W1A, BCDABCD7, 82112345, 671LSN123016, 3000000000000, 091640, 0040916440 02000W1AB, CDABCD78, 21123456, 71LSN1230163, 0000000000000, 916400, 0409164400 2000W1ABC, DABCD782, 11234567, 1LSN12301630, 0000000000009, 164000, 4091644002 000W1ABCD, ABCD7821, 12345671, LSN123016300, 0000000000091, 640004, 0091644002