使用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
答案取决于您是否只需要修复字符串(删除多余的引号)或是否必须保留数字不加引号。
前者更简单:
在这种情况下,你最好的方法是从输入字符串中删除引号,然后让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