2016-08-08 2 views
1

Ich versuche, eine tabulatorgetrennte Textdatei ohne Header mit PowerShell anpassen und haben es die Ausgabe in die gleiche Tab-getrennte Textdatei schreiben. Derzeit sind die Quelldaten wie folgt;Beschränken CSV-Spalte Länge mit Powershell

  • AAA \ t BBBBBB \ t CCCCCCCCCCC
  • AAAA \ t BBBB \ t AAAABBBBBCCCCCCC

Jetzt Spalte Nummer drei sollte nur, was den Ausgang Blick auf die ersten 5 Zeichen begrenzt werden wie folgt;

  • AAA \ t BBBBBB \ t CCCCC
  • AAAA \ t BBBB \ t AAAAB

Wie kann ich das erreichen?

Antwort

2

Der folgende Code wird eine CSV-Datei Import-Csv mit importieren und dann einer Schleife durch alle Linien, einen Teils (5 in der Länge) die Schaffung der dritten Spalte vor dem Schreiben der Zeile in eine neue CSV-Datei.

$oldCSV = "T:\OLD.csv" 
$newCSV = "T:\New.csv" 

Import-Csv -Delimiter "`t" -Path $oldCSV -Header "1","2","3" | ForEach-Object { 
    "{0}`t{1}`t{2}" -f $_.1,$_.2,($_.3).Substring(0,[Math]::Min(5,($_.3).Length)) >> $newCSV 
} 
+0

Es wird sich aufregen, wenn in jedem der verbleibenden Felder auch Werte in Anführungszeichen gesetzt sind. hier nicht unbedingt zu erwarten, aber trotzdem eine Einschränkung. –

+0

Danke! Dies löst es perfekt. – user58602

1

Kürzt es nach dem Import:

Import-Csv ... | ForEach-Object { if ($_.Column3.Length -gt 5) { $_.Column3.Substring(0, 5) }; $_ } 

Wenn Sie über alle Eigenschaften, um die Regel anwenden wollen Sie eine generische Eigenschaft Schleife stattdessen eine bestimmte Eigenschaft von Targeting mit Namen erstellen könnten.

Import-Csv ... | ForEach-Object { 
    foreach ($property in $_.PSObject.Properties) { 
     if ($property.Value.Length -gt 5) { 
      $property.Value = $property.Value.Substring(0, 5) 
     } 
    } 
    $_ 
} 

Import-Csv selbst wird das nicht für Sie tun, es ist nicht der Job, für den es trainiert wird.

+1

Entschuldigung, mehr Eile weniger Geschwindigkeit. Ein Fix wird in einem Moment mitkommen. –

0

Sie können Ihre eigenen Header-Informationen Import-Csv passieren:

# Import the file with the proper delimiter and dummy headings 
(Import-Csv foo.tsv -delim "`t" -header c1,c2,c3) | 
    # Truncate the third column accordingly. Regex because I'm lazy. 
    ForEach-Object { $_.c3 = $_.c3 -replace '(?<=^.{5}).*'; $_ } | 
    # Convert back to TSV. This also emits the headers 
    ConvertTo-Csv -NoTypeInformation -delim "`t" | 
    # Remove the headers again 
    Select -Skip 1 | 
    # Write back to file 
    Out-File foo.tsv -Encoding UTF8 
+0

Sie müssen nicht unbedingt positive Look-Behind verwenden. Eine Alternative: '-replace '^ (. {5}). *', '$ 1'' –

+0

@ChrisDent: Ich weiß, ich tendiere einfach dazu, den Text nicht durch sich selbst zu ersetzen, wenn ich ihm helfen kann. Nennen Sie es eine Angewohnheit :-) – Joey

+0

Dies scheint nicht zu funktionieren, ich bin am Ende mit einer leeren Datei. Ich habe es auch mit Chris versucht. Was könnte schief gehen? – user58602

Verwandte Themen