powershell ConvertTo-csv doubleQuotes的位置

时间:2014-08-29 16:37:05

标签: powershell csv

我使用以下查询将少量事件日志条目导出到csv文件中。

powershell "Get-WinEvent -EA SilentlyContinue -FilterHashtable @{ProviderName='Microsoft-Windows-Power-Troubleshooter';ID=1}| SELECT-Object @{l = 'TimeCreated'; e = {Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'}},@{l = 'DayOfWeek'; e = {(Get-Date $_.TimeCreated).DayOfWeek}},ID,@{Name='Source'; e={'Source=EventLog'}},{'Message='+$_.MESSAGE}|ConvertTo-Csv -NoTypeInformation | %{ $_ -replace """`r`n""",',' }  | select -Skip 1| Out-File -Append C:\LOGS\TIMELINE\TEMP.csv"

这是我现在得到的输出:

"2014-08-14 13:51:46","Thursday","1","Source=EventLog","Message=The system has resumed from sleep"

如何修改查询以便我的出局成为:

"2014-08-14 13:51:46","Thursday","1",Source="EventLog",Message="The system has resumed from sleep

(双引号位置更改仅包含值) [后处理输出文件将是我的最后一个选择......如果可以在powershell中做的话会很好..]

2 个答案:

答案 0 :(得分:1)

另一种方法。虽然我对它的印象并不像我想的那样让它变得更加复杂。

我已经在你的代码中添加了一些返回值,因为单行很难滚动

powershell "Get-WinEvent -EA SilentlyContinue -FilterHashtable @{ProviderName='Microsoft-Windows-Power-Troubleshooter';ID=1}| 
    SELECT-Object @{l = 'TimeCreated'; e = {Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'}},@{l = 'DayOfWeek'; e = {(Get-Date $_.TimeCreated).DayOfWeek}},ID,@{Name='Source'; e={'Source=EventLog'}},{'Message='+$_.MESSAGE}|
    ConvertTo-Csv -NoTypeInformation | 
    %{ $_ -replace """`r`n""",',' }  | select -Skip 1| 
    # The part i have added
    %{($_ -split "," | %{
         If ($_.Contains("=")){
               ($_ -replace "`"") -replace "=(.*)",'="$1"'
         } else {$_ }}) -join ","} |
    # The end of my addition
    Out-File -Append C:\LOGS\TIMELINE\TEMP.csv"

对于我在out文件使用"2014-08-14 13:51:46","Thursday","1","Source=EventLog","Message=The system has resumed from sleep"之前添加的块,它将被发送到Out-File。

我用它做的是将字符串从单行拆分并单独处理每个元素。包含等于=符号的每一行我首先删除所有引号。然后类似于Mad的例子,我把等号后面的所有东西都拿出来并在它周围加上引号。然后在它被发送到文件之前再次使用,加入它,以便它像csv条目一样。

我知道这可以改进,但是我可以从OP的Get-WMIEvent获得正确的输出,所以我不能在没有当前代码风险的情况下提高效率。

基于评论

尝试将这部分代码插入到outfile之前的现有语句中。

%{($_ -split "," | %{If ($_.Contains("=")){($_ -replace "`"") -replace "=(.*)",'="$1"'} else {$_ }}) -join ","} 

答案 1 :(得分:0)

这样做。我在末尾附近添加了一个ForEach循环,用","<text>=

替换",<text>="
powershell "Get-WinEvent -EA SilentlyContinue -FilterHashtable @{ProviderName='Microsoft-Windows-Power-Troubleshooter';ID=1}| SELECT-Object @{l = 'TimeCreated'; e = {Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'}},@{l = 'DayOfWeek'; e = {(Get-Date $_.TimeCreated).DayOfWeek}},ID,@{Name='Source'; e={'Source=EventLog'}},{'Message='+$_.MESSAGE}|ConvertTo-Csv -NoTypeInformation | %{ $_ -replace """`r`n""",',' }  | select -Skip 1| %{$_ -replace "`",`"(\w+?=)", "`",`$1`""} | Out-File -Append C:\LOGS\TIMELINE\TEMP.csv"

修改:我在=)之后缺少引号。原始ForEach循环:

%{$_ -replace "`",`"(\w+?=), "`",`$1`""}

修正:

%{$_ -replace "`",`"(\w+?=)", "`",`$1`""}

Edit2:如果这是错误的,您可以使用单引号括起参数。它看起来像是:

%{$_ -replace '","(\w+?\=)', '",$1"'}

这消除了对转义字符的任何需求。

编辑3:请尝试此操作,看看它是否提供了所需的输出:

powershell -command "& {Get-WinEvent -EA SilentlyContinue -FilterHashtable @{ProviderName='Microsoft-Windows-Power-Troubleshooter';ID=1}| ForEach{'""{0}"",""{1}"",""{2}"",Source=""EventLog"",Message=""{3}""' -f (Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'), ((Get-Date $_.TimeCreated).DayOfWeek), $_.ID, ($_.MESSAGE -join ',')}| Out-File -Append C:\temp\TEMP.csv}"