2016-11-29 14 views
1

У меня есть набор исходных данных, который состоит из текстовых файлов, где столбцы разделены одним или несколькими пробелами, в зависимости от ширины значения столбца. Данные корректируются правильно, т. Е. Пробелы добавляются до фактических данных.Как обрабатывать текстовый файл с несколькими пробелами в качестве разделителя

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

ответ

0

Вы можете создать пользовательский экстрактор или более просто, импортировать данные в один ряд, то разделить и очистить и с помощью методов C# доступны для вас в U-SQL, как Split и IsNullOrWhiteSpace, что-то вроде этого:

My right-aligned sample data

// Import the row as one column to be split later; NB use a delimiter that will NOT be in the import file 
@input = 
    EXTRACT rawString string 
    FROM "/input/input.txt" 
    USING Extractors.Text(delimiter : '|'); 


// Add a row number to the line and remove white space elements 
@working = 
    SELECT ROW_NUMBER() OVER() AS rn, new SqlArray<string>(rawString.Split(' ').Where(x => !String.IsNullOrWhiteSpace(x))) AS columns 
    FROM @input; 


// Prepare the output, referencing the column's position in the array 
@output = 
    SELECT rn, 
      columns[0] AS id, 
      columns[1] AS firstName, 
      columns[2] AS lastName 
    FROM @working; 


OUTPUT @output 
TO "/output/output.txt" 
USING Outputters.Tsv(quoting : false); 

Мои результаты:

My Results HTH

1

@ Решение wBob работает, если ваша строка вписывается в строку (128kB). В противном случае напишите свой собственный экстрактор, который исправляется с извлечением. В зависимости от того, какую информацию у вас есть в формате, вы можете записать ее, используя input.Split(), чтобы разбить на строки, а затем разбить строки на основе правил пробелов, как показано ниже (полный пример шаблона Extractor равен here), или вы можете написать одно подобное тот, который описан в this blog post.

public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow outputrow) 
    { 
     foreach (Stream current in input.Split(this._row_delim)) 
     { 
      using (StreamReader streamReader = new StreamReader(current, this._encoding)) 
      { 
       int num = 0; 
       string[] array = streamReader.ReadToEnd().Split(new string[]{this._col_delim}, StringSplitOptions.None).Where(x => !String.IsNullOrWhiteSpace(x))); 
       for (int i = 0; i < array.Length; i++) 
       { 
        // Now write your code to convert array[i] into the extract schema 
       } 
      } 
      yield return outputrow.AsReadOnly(); 
     } 
    } 
} 
+0

Отличное дополнение и важный пункт о пределе 128 КБ, спасибо @MichaelRys. – wBob