我意識到你不熟悉PowerShell,但它可能是你應該研究的東西。我在3年前就已經處於您的位置,現在90%的時間使用它來代替批處理文件。
在PowerShell中這相對簡單。您可以通過ForEach循環運行字符串數組,創建一個對象併爲每個屬性添加成員,然後在到達新的Source行時輸出前一個對象並啓動一個新對象。它會自動爲您創建一個數組,並且您可以將其傳送到Export-CSV
。
我會特別做的是將變量$Record
設置爲空字符串。
然後我得到文件的內容,並將其傳遞到Where語句,以匹配RegEx匹配的每一行。這將創建自動變量$Matches
,該變量沿着管線傳遞。該匹配將捕獲第一個冒號前的所有內容,然後是冒號後面的所有內容以及任何尾隨的空格。
這是通過管道連接到ForEach循環,每循環執行一次。它檢查是否$Matches[1]
(第一個冒號前的所有內容)='源'。如果是,則輸出$Record
的當前內容,並創建一個新的$Record
作爲具有一個屬性的自定義對象:'Source'= $Matches[2]
(第一個冒號和尾部空白後的所有內容)。如果$Matches[1]
不等於'來源',則它將新屬性添加到$Record
,其中屬性名稱爲$Matches[1]
,值爲$Matches[2]
。爲了保持清潔,我在$Matches[2]
上執行了.Trim()
方法,以確保沒有前導或尾隨空格或換行符或任何奇怪的東西。
在我處理完所有事情後,我再次通過Where語句運行它以刪除空白記錄(例如我預先設置的第一個)。然後我再輸出$Record
。至於你說你在一個CSV想這個我已經管道整個循環和後$Record
到Export-CSV
$Record = ""
$Output = @()
Get-Content Input_data.txt | Where{$_ -match "([^:]*):\s*?(\S.*)"}|Foreach{
if($Matches[1] -eq "Source"){
$Output += $Record
$Record = [PSCustomObject]@{'Source'=$Matches[2].trim()}
}else{
$Record | Add-Member $Matches[1] $Matches[2].trim()
}
}|?{![string]::IsNullOrEmpty($_)} | Export-Csv Output.csv -NoTypeInformation
$Output += $Record
$Output | Export-Csv Output.csv -NoTypeInformation -Append
結果是這些內容的CSV文件:
"Source","Destination","Total bytes","MB per min"
"X:\folder_abc","Y:\Abc_folder","208,731,021","256.5"
"X:\folder_def","Y:\xyz_folder","123,134,545","326"
"X:\folder_foo","Y:\Baz_folder","24,344","532"
或者,如果你不」牛逼管使其出口CSV它只是顯示它在屏幕上:
Source Destination Total bytes MB per min
------ ----------- ----------- ----------
X:\folder_abc Y:\Abc_folder 208,731,021 256.5
X:\folder_def Y:\xyz_folder 123,134,545 326
X:\folder_foo Y:\Baz_folder 24,344 532
編輯:好吧,你得到添加 - 錯誤會員使用它的方式。這意味着你有一個較舊版本的PowerShell。有2個解決方案。首先,我的建議是更新PowerShell。有時候這不是一個選項,所以沒關係,我們可以使用它。
如果您使用的是PS v1或v2,則使用添加成員的方式不起作用。我如何使用它是,如果您將對象傳遞給添加成員,然後指定2個字符串參數,它假定第一個是NotePropertyName,第二個是NotePropertyValue。你可以看到上面的樣子。因此,要怎麼做,如果不工作是使用了更詳細的語法:
Add-Member -InputObject $TargetVariable -MemberType NoteProperty -Name Name -Value Value
在我們的情況下,它意味着我們更換添加會員行這樣的:
Add-Member -InputObject $Record -MemberType NoteProperty -Name $Matches[1] -Value $Matches[2].trim()
你去了並改變了輸入。這很容易修復...將RegEx匹配從"([^:]*):\s*?(\S.*)"
更改爲"([^=]*)=\s*?(\S.*)"
。所以,把他們放在一起:
$Record = ""
$Output = @()
Get-Content Input_data.txt | Where{$_ -match "([^=]*)=\s*?(\S.*)"}|Foreach{
if($Matches[1] -eq "Source"){
If(![String]::IsNullOrEmpty($Record)){$Output += $Record}
$Record = [PSCustomObject]@{'Source'=$Matches[2].trim()}
}else{
Add-Member -InputObject $Record -MemberType NoteProperty -Name $Matches[1] -Value $Matches[2].trim()
}
}
$Output += $Record
$Output | Export-Csv C:\Temp\Output.csv -NoTypeInformation
EDIT2:我想我忘記了-append是不是在舊版本的PowerShell的出口-CSV的選項。這可以通過收集所有數據並在最後輸出一次來實現。我已經更新了我的答案中的最後一個腳本,通過在頂部附近創建一個空數組$Output
,然後在循環中,而不是僅在輸出完成時輸出$Record
,我將它添加到數組中。我也修改了這一行以通過If語句來避免向數組添加空白記錄。然後在ForEach循環之後,我將最後一條記錄添加到數組中,最後將整個記錄數組輸出到CSV文件。
這個問題似乎是題外話,因爲它是要求別人做爲你工作。你有什麼嘗試? – 2014-09-03 19:58:52
請在您的問題中顯示您嘗試的內容。 – 2014-09-03 20:06:11
您的「所需格式」不正確 - 「總字節數」列中的逗號會影響格式。可能最好引用所有值。 – dbenham 2014-09-04 03:12:20