使用ConvertTo-Csv完全删除双引号很简单,但我需要的是仅单独引用引号。
我的意思是我从Invoke-Sqlcmd输出一个产生以下数据的查询:1,“George Burns”,18,0(SQL查询为字符串添加引号)
ConvertTo-Csv的输出变为:“1”,“”“George Burns”“”,“18”,“0”
所以 - 我需要保留字符串周围的引号并摆脱其余部分。有什么建议我可以解决这个问题吗?
Invoke-Sqlcmd -ServerInstance SQLSrv01 `
-Database MyDatabase `
-InputFile "c:\temp\MyQuery.sql" | `
ConvertTo-Csv -NoTypeInformation -Delimiter "," | `
Select-Object -Skip 1 | % {$_ -replace '', ""} | `
Out-File ("C:\temp\test.csv") -Force -Encoding UTF8
答案 0 :(得分:1)
答案取决于您是否只需要修复字符串(删除多余的引号)或者是否必须保留数字不加引号。
前者更简单:
在这种情况下,您最好的方法是从输入字符串中删除引号,然后让ConvertTo-Csv
继续执行工作(甚至只使用Export-Csv
,因为看起来这就是您要做的所有事情无论如何。你可以通过多种方式实现这一目标,但最简单的可能是Select-Object
上的计算属性:
(代码示例注释:你没有给我们列名,所以我正在编写它们;我也正在删除反引号,因为它们不推荐,管道后不需要)
Invoke-Sqlcmd -ServerInstance SQLSrv01 -Database MyDatabase -InputFile "c:\temp\MyQuery.sql" |
Select-Object -Property Id,@{Name='Actor';Expression={$_.Actor.Trim('"')}},Age,Warrants |
Export-Csv -LiteralPath C:\temp\test.csv -Encoding UTF8
在这种情况下,我建议您编写自己的CSV转换功能(说实话,您也应该对上述情况也这样做),其中您不使用ConvertTo-Csv
。
您可以使用输入对象上的.PSObject
属性枚举属性并获取其值。这是一个我没有经过充分测试的功能:
function ConvertTo-MyCsv {
[CmdletBinding()]
param(
[Parameter(
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName
)]
[Object]
$InputObject ,
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Delimiter = ',' ,
[Parameter()]
[Switch]
$NoStrip
)
Begin {
$headers = $false
}
Process {
if (-not $headers) {
$InputObject.PSObject.Properties.Name.ForEach({'"{0}"' -f $_}) -join $Delimiter
}
$InputObject.PSObject.Properties.Value.ForEach({
if ($_ -is [String]) {
$value = if ($NoStrip) {
$_
} else {
$_.Trim('"')
}
'"{0}"' -f ($value -replace '"','""')
} else {
$_
}
}) -join $Delimiter
}
}
像这样使用:
Invoke-Sqlcmd -ServerInstance SQLSrv01 -Database MyDatabase -InputFile "c:\temp\MyQuery.sql" |
ConvertTo-MyCsv