簡體   English   中英

從txt文件中獲取數據並將其導出為CSV

[英]Fetch data from txt file and export it to CSV

我在文本文件中有以下數據。

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

找到了一種超級簡單的方法來解決您的問題,方法是創建哈希表並將其導出到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

此解決方案假定您的文本文檔格式正確。

您在正確的道路上。 但是,有兩種方法可以做到這一點。 這是最簡單,最直接的方法。 但是,由於輸入文件中分別列出了所有不同的列,因此您至少需要先占先知道列數和所使用的定界符(這里是分號)。

堅持使用示例文本文件以及盡可能多的代碼,這就是您要執行的操作。

$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

固定讀取計數的一種替代方法是使用正則表達式$ data =(Get-Content。\\ data.txt -Raw)-split“`n(?= author)”在RegEX的第一個字段處進行拆分。

這實際上是一個非常好的主意,我喜歡。 唯一的問題是,必須確保每個屬性組始終始終將第一列列出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM