2013-02-04 5 views
0

Veuillez prendre en compte les csv séparés par un point virgule.Fichiers csv séparés basés sur les valeurs

27356456;2;4001;3005;2100;20130125; 
27356457;2;4001;3005;2100;20130125; 
27356458;2;4001;3005;2100;20130125; 
27356459;2;4002;3005;2100;20130125; 
27356460;2;4002;3005;2100;20130125; 
27356461;2;4006;3006;2104;20130125; 
27356462;2;4006;3006;2104;20130125; 
27356463;2;4006;3006;2104;20130125; 
27356464;2;4006;3006;2104;20130125; 

Je veux stocker au-dessus des lignes dans des fichiers csv séparés en fonction des valeurs en position 2, 3 et 4 (soit toutes les lignes avec 4001, 3005, 2100 dans un fichier csv et tous les 4002, 3005, 2100 un autre fichier et toutes les lignes avec 4006, 3006 et 2104 dans un autre fichier).

Les valeurs à ces positions peuvent varier dans les données réelles. Je pense que cela peut être réalisé avec Linq ou? Tout indice sera apprécié.

private void ProcessTextFile(FileInfo csvFile) 
{ 
    using (StreamReader sr = new StreamReader(csvFile.FullName, Encoding.UTF8)) 
    { 
    while (sr.Peek() >= 0) 
    { 
     string line = sr.ReadLine(); 
     string[] words = line.Split(";"); 
     ... 
    } 
    } 
} 

Répondre

0

Il vous suffit de créer une clé unique pour chaque fichier ... quelque chose comme ...

string fileKey = string.Format("{0}.{1}.{2}", words[2], words[3], words[4]); 

Ajoutez juste un nouveau fichier basé sur lequel fileKey est découvert.

string filePath = @"C:\output\" + fileKey + ".csv"; 
File.AppendAllText(filePath, line); 
+0

Merci. Bonne solution. Mais le problème est un peu complexe car la ligne csv contient aussi des noms de fichiers d'images, qui doivent également être copiés dans le répertoire de csvs. Cela doit être fait immédiatement pour s'assurer que toutes les lignes et images sont copiées. – mrd

+1

@mrd pourquoi ne pas créer un répertoire contenant la fileKey? Que voulez-vous dire par "à la fois"? – derape

+0

@derape: En fait, j'ai déjà une structure de répertoires. Par exemple, C: \ PrepareImport \ 2100 \ 3005 \ 4001 \ et C: \ PrepareImport \ 2100 \ 3005 \ 4002 \ et ainsi de suite ... Les trois premières lignes du fichier csv ci-dessus seront stockées dans C: \ PrepareImport \ 2100 \ 3005 \ 4001 \ et donc un ... "à la fois" veut dire, je veux séparer les lignes dans un dictionnaire ou quelque chose, puis écrire les lignes dans des fichiers csv distincts au lieu d'ajouter. – mrd

0
var pathTemplate = @"C:\PrepareImport\{0}\{1}\{2}\filename.csv"; 
File.ReadAllLines(fileName) 
    .GroupBy(x => x.Split(';').Skip(2).Take(3)) 
    .ToList() 
    .ForEach(x => File.AppendAllLines(
     string.Format(pathTemplate, x.Key[0], x.Key[1], x.Key[2]), x)); 
0

Peut-être pour tous les fichiers d'une requête:

var allCsv = Directory.EnumerateFiles(dir, "*.csv") 
    .Select(path => new 
    { 
     Path = path, 
     Lines = File.ReadLines(path) 
      .Select(l => new { Split = l.Split(';')}) 
      .Where(x => x.Split.Length >= 6) 
      .Select(x => new { 
       Columns= x.Split 
        .Where((s, i) => i >= 2 && i <= 4) 
        .ToList() 
      }).ToList() 
    }) 
    .ToList(); 

// now you have all you need: 
foreach (var csv in allCsv) 
    foreach(var csvLine in csv.Lines) 
     Console.WriteLine("File:{0} Columns:{1}", csv.Path, string.Join(",", csvLine.Columns)); 

(modifier: Je dois avouer que voici le point où Linq est illisible plus):

Questions connexes