Получить данные из TXT-файла и экспортировать их в CSV - PullRequest
0 голосов
/ 17 октября 2018

У меня есть данные ниже в текстовом файле.

author   ; testname1
Revision ; 121
Date     ; 10/5/2018
Path     ; dev/test1
Message  ; notes: testdata1
author   ; testname2
Revision ; 1212
Date     ; 10/6/2018
Path     ; dev/test2
Message  ; notes: testdata2
author   ; testname3
Revision ; 1213
Date     ; 10/5/2018
Path     ; dev/test3
Message  ; notes: testdata3

Я хочу прочитать это и экспортировать в CSV, как показано ниже.

author,Revision,Date,Path,Message
testname1,121,10/5/2018,dev/test1,notes: testdata1
testname2,1212,10/6/2018,dev/test2,notes: testdata2
testname3,1213,10/5/2018,dev/test3,notes: testdata3

Есть предложения?

Я пробовал ниже код

$local:InputFilePath   = "path of file"
$local:OutFilePathCSV  = "path of csv file"
$local:CSVDelimiter    = ","
$local:OutDataList     = New-Object -TypeName System.Collections.Arraylist
$local:CurrentDataList = New-Object -TypeName System.Collections.Hashtable

Select-String -Path $InputFilePath -Pattern "^[\s]" -NotMatch | ForEach-Object {
    $local:CurrentLine  = ($_.Line).TrimEnd()
    $CurrentLine

    $OutDataList.Add($(New-Object -TypeName System.Management.Automation.PSObject -Property $CurrentDataList)) | Out-Null
    $CurrentDataList.Clear()
    if ($CurrentLine -match "^[\s]*([\w]*)[\s]+(.*)") {
        $CurrentDataList.Add($matches[1], $matches[2])
        $matches[1]
        $matches[2]

        #break
    }
}
$OutDataList |
    Sort-Object -Property Serial |
    Select-Object -Property author, Revision, Date, Action, Path |
    Export-Csv -Path $OutFilePathCSV -Delimiter $CSVDelimiter -NoTypeInformation

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

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

Придерживаясь вашего примера текстового файла, и насколько это возможно, ваш код, вот как вы бы это сделали.

$InputFilePath     = "path of file"
$OutFilePathCSV    = "path of csv file"
$CSVDelimiter      = ","
$OutDataList       = New-Object -TypeName System.Collections.Arraylist
$ColumnNumbers     = 5
$InputFileDelimter = ';'

$InputFileData = Select-String -Path $InputFilePath -Pattern "^[\s]" -NotMatch
for ($i = 0 ; $i -lt $InputFileData.count; $i += $ColumnNumbers) {
    $CurrentLine = New-Object PSObject
    for ($j = 0 ; $j -lt $ColumnNumbers; $j++) {
        if ($InputFileData[$i+$j].Line -match "^(.*)\s*$InputFileDelimter\s*(.*)\s*$") {
            $CurrentLine | Add-Member -MemberType NoteProperty -Name $matches[1] -Value $matches[2]
        }
    }
    $OutDataList.Add($CurrentLine)
}
$OutDataList |
    Select-Object -Property Author, Revision, Date, Action, Path |
    Export-Csv -Path $OutFilePathCSV -Delimiter $CSVDelimiter -NoTypeInformation

Советы / информация:

  • С вашим регулярным выражением "^[\s]*([\w]*)[\s]+(.*)"
    • ^[\s]* является избыточным, поскольку вы уже исключаете строки, начинающиеся с пробела в строке выбора.
    • ([\w]*) не будет захватывать столбцы с пробелами вимя (здесь не обязательно, но для использования в будущем).
    • (.*) также захватит разделитель.
  • С регулярным выражением "^(.*)\s*$InputFileDelimter\s*(.*)\s*$"
    • ^(.*)\s* захватывает полные имена столбцов без пробелов перед разделителем.Вы можете поменять это на ^\w*, если это всегда будет только одно слово.
    • $InputFileDelimter\s*(.*)\s*$ будет захватывать все значение столбца без начального или конечного пробела.

Примечания:

  • $CSVDelimter не требуется, поскольку Export-CSV по умолчанию использует запятую.
  • У вас нет столбца с именем SerialТак что сортировка ничего не делает в вашем коде.

Надеюсь, это поможет!Удачи в PowerShell!

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

Из комментария к другому ответу ниже: Извлечь данные из txt-файла и экспортировать их в CSV

Альтернативой фиксированному числу считываний является разделение первого поля с помощью RegEX с использованием позитивного просмотра вперед $ data = (Get-Content. \ Data.txt -Raw) -split "` n (? = Author) "

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

0 голосов
/ 17 октября 2018

Найден супер простой способ решить вашу проблему, создав хеш-таблицу и экспортировав ее в csv:

#requires -Version 3

$path = 'C:\Temp\data.txt'
$data = Get-Content -Path $path -ReadCount 5

$collection = foreach ($obj in $data)
{
    $out = [ordered]@{}
    foreach ($line in $obj.Split("`n"))
    {
        $a, $b = ($line -split ';').Trim()
        $out[$a] = $b
    }
    [pscustomobject]$out
}

$newPath = 'C:\Temp\file.csv'
$collection | Export-Csv -Path $newPath -Encoding ascii -NoTypeInformation -Force

Это решение предполагает, что ваш текстовый документ правильно сформирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...