2016-11-29 3 views
1

Ich habe einen Quelldatensatz, der aus Textdateien besteht, wobei die Spalten durch ein oder mehrere Leerzeichen getrennt sind, abhängig von der Breite des Spaltenwerts. Die Daten werden richtig eingestellt, d. H. Die Leerzeichen werden vor den tatsächlichen Daten hinzugefügt.So behandeln Sie Textdatei mit mehreren Leerzeichen als Trennzeichen

Kann ich einen der integrierten Extraktoren verwenden oder muss ich einen benutzerdefinierten Extraktor implementieren?

Antwort

0

Sie können einen benutzerdefinierten Extraktor oder einfacher erstellen, die Daten importieren als eine Zeile dann aufgeteilt und sauber und es mit C# Methoden zur Verfügung, um Sie in U-SQL wie Split und IsNullOrWhiteSpace, etwa so:

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); 

Meine Ergebnisse:

My Results HTH

1

@ wBobs Lösung funktioniert, wenn Ihre Zeile in eine Zeichenfolge (128kB) passt. Schreiben Sie andernfalls Ihren benutzerdefinierten Extraktor, der mit der Extraktion behoben wird. Abhängig davon, welche Informationen Sie für das Format haben, können Sie es schreiben, indem Sie input.Split() verwenden, um es in Zeilen aufzuteilen, und dann die Zeilen basierend auf Ihren Leerraumregeln aufteilen (vollständiges Beispiel für Extractor-Muster ist here) oder Sie könnten eine ähnliche schreiben der in this blog post beschriebene.

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

Große Zugabe, und wichtiger Punkt über die 128KB Grenze, danke @MichaelRys. – wBob

Verwandte Themen