![](/img/trans.png)
[英]Extract Data from .txt files and export it to a .csv file #powershell
[英]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.