2017-10-06 5 views
0

J'importe des données d'un fichier CSV délimité par des tubes à MySQL à l'aide d'une instruction LOAD DATA INFILE. Je termine des lignes en utilisant '\ r \ n'. Mon problème est que certaines des données dans chaque rangée ont '\ r \ n' dedans, causant le chargement à l'erreur. J'ai des fichiers similaires qui utilisent juste '\ n' dans les données pour indiquer les sauts de ligne, et cela ne cause aucun problème.Suppression des retours chariot à partir de la valeur de données CSV

Exemple BON CSV

School|City|State|Country\r 
Harvard University|Cambridge|MA|USA\r 
Princeton University|Princeton|New 
Jersey 
|USA\r 

Exemple BAD CSV

School|City|State|Country\r 
Harvard University|Cambridge|MA|USA\r 
Princeton University|Princeton|New\r 
Jersey\r 
|USA\r 

est-il un moyen de pré-traiter le CSV, en utilisant sed, awk ou perl, pour nettoyer le retour chariot supplémentaire dans les valeurs de la colonne?

+0

Oui Ed, malheureusement. C'est le format qui m'est donné et je n'ai pas la possibilité de le changer. – Gavi

+0

les lignes ont-elles un nombre fixe de champs? –

+0

@ChrisTurner oui il y a un nombre fixe de champs – Gavi

Répondre

0

Avec awk GNU RS multi-CHAR et RT:

$ awk -v RS='([^|]+[|]){3}[^|]+\r\n' -v ORS= '{$0=RT; gsub(/\r/,""); sub(/\n$/,"\r\n")} 1' file | cat -v 
School|City|State|Country^M 
Harvard University|Cambridge|MA|USA^M 
Princeton University|Princeton|New 
Jersey 
|USA^M 

Notez qu'il assume le nombre de champs est 4, donc si vous avez un autre nombre de champs puis changer 3 à ce numéro moins 1. le script POURRAIENT place calculer le nombre de champs en lisant la première ligne de votre entrée, si la première ligne ne peut pas avoir votre problème:

$ awk ' 
    BEGIN { RS="\r\n"; ORS=""; FS="|" } 
    FNR==1 { RS="([^|]+[|]){"NF-1"}[^|]+\r\n"; RT=$0 RT } 
    { $0=RT; gsub(/\r/,""); sub(/\n$/,"\r\n"); print } 
' file | cat -v 
School|City|State|Country^M 
Harvard University|Cambridge|MA|USA^M 
Princeton University|Princeton|New 
Jersey 
|USA^M 
1

Ceci est une solution possible en Perl. Il lit dans une ligne et s'il y a moins de 4 champs, il continue à lire dans la ligne suivante et à la fusionner jusqu'à ce qu'il ait 4 champs. Il suffit de changer la valeur de $number_of_fields au bon nombre.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $number_of_fields=4; 

while(<STDIN>) 
    { 
    s/[\r\n]//g; 
    my @fields=split(/\|/); 
    next if($#fields==-1); 

    while($#fields<$number_of_fields-1) 
     { 
     my $nextline=<STDIN> || last; 
     $nextline =~ s/[\r\n]//g; 
     my @tmpfields=split(/\|/,$nextline); 
     next if($#tmpfields==-1); 
     $fields[$#fields] .= "\n".$tmpfields[0]; 
     shift @tmpfields; 
     push @fields,@tmpfields; 
     } 
    print join("|",@fields),"\r\n"; 
    }