2015-04-27 2 views
0

Я хотел бы преобразовать плоский файл test.txt в плоский файл test-output.txt.Transform Flat File без разделителей

Ниже схема:


ПРИМЕР ВХОД: test.txt

COD/ID:37 
PRJ/NAME: Josephy Murphy 
PRJ/EMAIL: [email protected] 
PRJ/DESCRIPTION: test37, test37, test37 ... 

COD/ID:38 
PRJ/NAME: Paul Newman 
PRJ/EMAIL: [email protected] 
PRJ/DESCRIPTION: test38, test38, test38 ... 

. 
. 

Пример вывод: тест-output.txt (труба с разделителями без меток)

37|Josephy Murphy|[email protected]|test37, test37, test37 ... 
38|Paul Newman|[email protected]|test38, test38, test38 ... 
. 
. 


ссылки на скриншоты:
test.txt
test-output.txt

Я хочу, чтобы импортировать этот файл в SQL Server. Но файл test.txt (15 000 000 строк) не используется по умолчанию для импорта с разделителями.

Я буду использовать SSIS для импорта данных, но должен быть в формате CSV или другом формате с разделителями.

Я думал об использовании компонента REGEX или SSIS Script. Я знаю процедуру импорта с помощью файлов SSIS с форматированным текстом, но этот файл не отформатирован.

+0

Пожалуйста, разместите этот текст (или, по крайней мере, исчерпывающие образцы) в вопросе. И, пожалуйста, поделитесь тем, что вы пробовали. Это необходимо. –

+0

В чем проблема? Где вы застряли? –

+0

Я хочу импортировать этот файл в SQL Server. Но файл test.txt (15 000 000 строк) не используется по умолчанию для импорта с разделителями. Я буду использовать SSIS для импорта данных, но должен быть в формате CSV или другом формате с разделителями. Я думал об использовании REGIS или скриптового компонента SSIS. Что ты предлагаешь? –

ответ

2

С Regex, например:

class Program 
    { 
     private static Regex reg = new Regex(@"COD/ID:\s(?<id>\d+)\r\nPRJ/NAME:\s(?<name>.+?)\r\nPRJ/EMAIL:\s(?<email>\[email protected]\S+?\.\S+?)\r\nPRJ/DESCRIPTION:\s(?<description>.*?)(?:\n|$)"); 

     static void Main(string[] args) 
     { 
      string original = @" 
COD/ID: 37 
PRJ/NAME: Josephy Murphy 
PRJ/EMAIL: [email protected] 
PRJ/DESCRIPTION: test37, test37, test37 ... 

COD/ID: 38 
PRJ/NAME: Paul Newman 
PRJ/EMAIL: [email protected] 
PRJ/DESCRIPTION: test38, test38, test38 ..."; 


      string result = string.Join(
       "\n", 
       reg.Matches(original) 
       .Cast<Match>() 
       .Select(m => string.Format("{0}|{1}|{2}|{3}",m.Groups["id"].Value,m.Groups["name"].Value,m.Groups["email"].Value,m.Groups["description"].Value))); 
      Console.WriteLine(result); 
     } 
    } 

Редактировать

class Program 
{ 
    private static Regex reg = new Regex(@"COD/ID:\s(?<id>\d+)\r\nPRJ/NAME:\s(?<name>.+?)\r\nPRJ/EMAIL:\s(?<email>\[email protected]\S+?\.\S+?)\r\nPRJ/DESCRIPTION:\s(?<description>.*?)\r\n"); 

    static void Main(string[] args) 
    { 
     StringBuilder intermediateStringBuilder = new StringBuilder(); 

     using (StreamReader reader = new StreamReader(@"YourInputPath.txt",true)) 
     {    
      using (StreamWriter writer = new StreamWriter("YourOutputPath.txt")) 
      { 
       while (reader.Peek() > 0) 
       { 
        string line = reader.ReadLine(); 
        if (!string.IsNullOrWhiteSpace(line)) 
        { 
         intermediateStringBuilder.AppendLine(line); 
        } 
        else 
        { 
         WriteToFile(intermediateStringBuilder, writer); 
        } 
       } 
       WriteToFile(intermediateStringBuilder,writer); 
      } 
     } 
    } 

    private static void WriteToFile(StringBuilder intermediateStringBuilder, StreamWriter writer) 
    { 
     Match m = reg.Match(intermediateStringBuilder.ToString()); 
     writer.WriteLine("{0}|{1}|{2}|{3}", m.Groups["id"].Value, m.Groups["name"].Value, m.Groups["email"].Value, m.Groups["description"].Value); 
     intermediateStringBuilder.Clear(); 
    } 
} 
+0

Поздравляем! Идеальное решение с использованием регулярного выражения (регулярное выражение). –

+0

@ J.LopesSilvestre да, но с миллионами строк у вас, вероятно, возникают проблемы с памятью (я просто прочитал ваш комментарий) ... так что это должен быть пример, как это сделать с меньшими файлами –

+0

Действительно производительность нарушена! Затем решение будет читать строки за строкой и записывать в текстовый файл? Использование методов System.IO; читать и писать в текстовый файл. –

0

Вы можете сделать это без регулярных выражений в данном случае, поскольку контекст известно.

Используйте это:

public class EntryN 
{ 
    public string id { get; set; } 
    public string name { get; set; } 
    public string email { get; set; } 
    public string description { get; set; } 

    public EntryN() 
    { 
     this.id = this.name = this.email = this.description = string.Empty; 
    } 
    public string ToLine() 
    { 
     return this.id + "|" + this.name + "|" + this.email + "|" + this.description; 
    } 
} 

var entries = new List<EntryN>(); 
using (var sl = new StreamReader(@"c:\YOURPATH.txt", true)) 
{ 
    var entry = new EntryN(); 
    var line = string.Empty; 
    while ((line = sl.ReadLine()) != null) 
    { 
     if (line.StartsWith("COD/ID:")) 
      entry.id = line.Substring(8).Trim(); 
     else if (line.StartsWith("PRJ/NAME:")) 
      entry.name = line.Substring(10).Trim(); 
     else if (line.StartsWith("PRJ/EMAIL")) 
      entry.email = line.Substring(11).Trim(); 
     else if (line.StartsWith("PRJ/DESCRIPTION")) 
      entry.description = line.Substring(17).Trim(); 
     else if (line.Trim() == string.Empty) 
     { 
      entries.Add(entry); 
      entry = new EntryN(); 
     } 
    } 
    if (!entry.Equals(new EntryN())) 
     entries.Add(entry); 
    sl.Close(); 
} 

var resulted = entries.Select(p => p.ToLine()).ToList(); 

Выход:

enter image description here

EDIT: Другой код без отдельного класса, который будет писать напрямую, без создания дополнительных строк:

var id = string.Empty; 
var name = string.Empty; 
var email = string.Empty; 
var description = string.Empty; 
using (var sw = new StreamWriter(@"OUTPUT_FILE", false, Encoding.UTF8)) 
{ 
    using (var sl = new StreamReader(@"INPUT_FILE", true)) 
    { 
     var line = string.Empty; 
     while ((line = sl.ReadLine()) != null) 
     { 
      if (line.StartsWith("COD/ID:")) 
       id = line.Substring(8).Trim(); 
      else if (line.StartsWith("PRJ/NAME:")) 
       name = line.Substring(10).Trim(); 
      else if (line.StartsWith("PRJ/EMAIL")) 
       email = line.Substring(11).Trim(); 
      else if (line.StartsWith("PRJ/DESCRIPTION")) 
       description = line.Substring(17).Trim(); 
      else if (line.Trim() == string.Empty) 
      { 
       sw.WriteLine(string.Format("{0}|{1}|{2}|{3}", id, name, email, description)); 
       id = name = email = description = string.Empty; 
      } 
     } 
     if (!new string[] {id, name, email, description}.Any(p => string.IsNullOrWhiteSpace(p))) 
      sw.WriteLine(string.Format("{0}|{1}|{2}|{3}", id, name, email, description)); 
     sl.Close(); 
    } 
    sw.Close(); 
} 
+0

Поздравляем! Это сработало отлично! Спасибо. –

+0

Рад помочь. Пожалуйста, добавьте свои предыдущие попытки на вопрос, BTW, даже если они не увенчались успехом. Перед тем, как спросить, всегда старайтесь хотя бы что-то опубликовать в качестве доказательства ваших усилий. В противном случае ваш вопрос будет закрыт и, в конечном итоге, удален. –

+0

Хорошо. Спасибо за совет. –

Смежные вопросы