ConvertTo-Csv输出没有引号

时间:2014-06-06 04:33:28

标签: powershell

我使用ConvertTo-Csv来获取逗号分隔输出

 get-process | convertto-csv -NoTypeInformation -Delimiter ","

输出如下:

"__NounName","Name","Handles","VM","WS",".....

但是我希望得到没有引号的输出,比如

__NounName,Name,Handles,VM,WS....

14 个答案:

答案 0 :(得分:12)

这是一种删除引号的方法

get-process | convertto-csv -NoTypeInformation -Delimiter "," | % {$_ -replace '"',''} 

但是如果其中一个项目包含"它会被删除,那么它有一个严重的缺点!

答案 1 :(得分:4)

我今天在桌子上工作并想到了这个问题,因为我在记事本中预览了CSV文件,并决定看看其他人提出了什么。似乎很多人都过分复杂了解决方案 这是从PowerShell中的Export-Csv cmdlet生成的CSV文件中删除引号的一种非常简单的方法。

使用以下数据创建TEST.csv文件。

“ID”, “名称”, “国家”
“5”, “斯蒂芬妮”, “亚利桑那”
“4”, “梅兰妮”, “俄勒冈州”
“2”, “凯蒂”, “得克萨斯”
“8”, “史蒂夫”, “爱达荷”
“9”, “多利”, “田纳西”

另存为:TEST.csv

将文件内容存储在$ Test变量中
$ Test = Get-Content。\ TEST.csv

加载$ Test变量以查看get-content cmdlet的结果
$测试

再次加载$ Test变量并用逗号替换所有(“,”),然后通过删除每个引号来修剪开始和结束
$ Test.Replace( ' “”', “”)。TrimStart( ' “ ')。TrimEnd('”')

保存/替换TEST.csv文件
$ Test.Replace('“,”',“,”)。TrimStart('“')。TrimEnd('”')| Out-File。\ TEST.csv -Force -Confirm:$ false

使用Import-Csv和Get-Content测试新文件输出:
Import-Csv。\ TEST.csv
获取内容。\ TEST.csv

总而言之,可以使用2行代码完成工作
$ Test = Get-Content。\ TEST.csv
$ Test.Replace('“,”',“,”)。TrimStart('“')。TrimEnd('”')| Out-File。\ TEST.csv -Force -Confirm:$ false

答案 2 :(得分:3)

这与接受的答案非常相似,但它有助于防止意外删除"真实"引号。

$delimiter = ','
Get-Process | ConvertTo-Csv -Delimiter $delimiter -NoTypeInformation | foreach { $_ -replace '^"','' -replace "`"$delimiter`"",$delimiter -replace '"$','' }

这将执行以下操作:

  • 删除以行开头的引号
  • 删除以行结尾的引号
  • 替换仅使用分隔符包装分隔符的引号。

因此,出现问题的唯一方法是,如果其中一个值实际上不仅包含引号,而且特别是引号分隔符引用序列,这有望非常罕见。

答案 3 :(得分:3)

我遇到了这个问题,发现了这个问题,但对答案不满意,因为如果您使用的数据包含分隔符,它们似乎都会受到影响,应该保持引用。摆脱不必要的双引号是件好事。

以下解决方案似乎解决了一般情况下的此问题,以及可能导致问题的所有变体。

我在其他地方Removing quotes from CSV created by PowerShell找到了这个答案,并用它来编写SO社区的示例答案。

归因: 正则表达式的信用,100%归属于Russ Loski。

功能中的代码,Remove-DoubleQuotesFromCsv

function Remove-DoubleQuotesFromCsv
{
    param (
        [Parameter(Mandatory=$true)]
        [string]
        $InputFile,

        [string]
        $OutputFile
    )

    if (-not $OutputFile)
    {
        $OutputFile = $InputFile
    }

    $inputCsv = Import-Csv $InputFile

    $quotedData = $inputCsv | ConvertTo-Csv -NoTypeInformation

    $outputCsv = $quotedData | % {$_ -replace  `
        '\G(?<start>^|,)(("(?<output>[^,"]*?)"(?=,|$))|(?<output>".*?(?<!")("")*?"(?=,|$)))' `
        ,'${start}${output}'}

    $outputCsv | Out-File $OutputFile -Encoding utf8 -Force
}

测试代码

$csvData = @"
id,string,notes,number
1,hello world.,classic,123
2,"a comma, is in here","test data 1",345
3,",a comma, is in here","test data 2",346
4,"a comma, is in here,","test data 3",347
5,"a comma, is in here,","test data 4`r`nwith a newline",347
6,hello world2.,classic,123
"@

$data = $csvData | ConvertFrom-Csv
"`r`n---- data ---"
$data

$quotedData = $data | ConvertTo-Csv -NoTypeInformation
"`r`n---- quotedData ---"
$quotedData

# this regular expression comes from:
# http://www.sqlmovers.com/removing-quotes-from-csv-created-by-powershell/
$fixedData = $quotedData | % {$_ -replace  `
  '\G(?<start>^|,)(("(?<output>[^,"\n]*?)"(?=,|$))|(?<output>".*?(?<!")("")*?"(?=,|$)))' `
  ,'${start}${output}'}
"`r`n---- fixedData ---"
$fixedData

$fixedData | Out-File e:\test.csv -Encoding ascii -Force
"`r`n---- e:\test.csv ---"
Get-Content e:\test.csv

测试输出

---- data ---

id string               notes                       number
-- ------               -----                       ------
1  hello world.         classic                     123   
2  a comma, is in here  test data 1                 345   
3  ,a comma, is in here test data 2                 346   
4  a comma, is in here, test data 3                 347   
5  a comma, is in here, test data 4...              347   
6  hello world2.        classic                     123   

---- quotedData ---
"id","string","notes","number"
"1","hello world.","classic","123"
"2","a comma, is in here","test data 1","345"
"3",",a comma, is in here","test data 2","346"
"4","a comma, is in here,","test data 3","347"
"5","a comma, is in here,","test data 4
with a newline","347"
"6","hello world2.","classic","123"

---- fixedData ---
id,string,notes,number
1,hello world.,classic,123
2,"a comma, is in here",test data 1,345
3,",a comma, is in here",test data 2,346
4,"a comma, is in here,",test data 3,347
5,"a comma, is in here,","test data 4
with a newline","347"
6,hello world2.,classic,123

---- e:\test.csv ---
id,string,notes,number
1,hello world.,classic,123
2,"a comma, is in here",test data 1,345
3,",a comma, is in here",test data 2,346
4,"a comma, is in here,",test data 3,347
5,"a comma, is in here,","test data 4
with a newline","347"
6,hello world2.,classic,123

答案 4 :(得分:3)

生成文件后,即可运行

set-content FILENAME.csv ((get-content FILENAME.csv) -replace '"')

答案 5 :(得分:2)

根据您的CSV数据的病态(或“全功能”)的方式,已发布的解决方案之一已经可以使用。

Kory Gill发布的解决方案几乎是完美的 - 剩下的唯一问题是对于包含行分隔符\r\n的单元格也会删除引号,这会导致许多工具出现问题。

解决方案是在字符类表达式中添加换行符:

$fixedData = $quotedData | % {$_ -replace  `
'\G(?<start>^|,)(("(?<output>[^,"\n]*?)"(?=,|$))|(?<output>".*?(?<!")("")*?"(?=,|$)))' `
,'${start}${output}'}

答案 6 :(得分:0)

我没有花太多时间寻找删除引号。但是,这是一种解决方法。

get-process | Export-Csv -NoTypeInformation -Verbose -Path $env:temp\test.csv
$csv = Import-Csv -Path $env:temp\test.csv

这是一个快速的解决方法,可能有更好的方法来做到这一点。

答案 7 :(得分:0)

我发现Kory的答案不适用于原始字符串连续包含多个空白字段的情况。即“ABC”,“0”很好,但“ABC”,,,“0”没有得到妥善处理。它在“,,,”之后停止替换引号。我通过在第一个参数的末尾附近添加“|(?<output>)”来修复它,如下所示:

% {$_ -replace  `
    '\G(?<start>^|,)(("(?<output>[^,"]*?)"(?=,|$))|(?<output>".*?(?<!")("")*?"(?=,|$))|(?<output>))', `
    '${start}${output}'}

答案 8 :(得分:0)

我是根据我的需要写的:

function ConvertTo-Delimited {

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [psobject[]]$InputObject,
        [string]$Delimiter='|',
        [switch]$ExcludeHeader
    )
    Begin {

        if ( $ExcludeHeader -eq $false ) {
            @(
                $InputObject[0].PsObject.Properties | `
                Select-Object -ExpandProperty Name
            ) -Join $Delimiter          
        }

    }
    Process {

        foreach ($item in $InputObject) {
            @(
                $item.PsObject.Properties | `
                Select-Object Value | `
                ForEach-Object { 
                    if ( $null -ne $_.Value ) {$_.Value.ToString()} 
                    else {''} 
                }
            ) -Join $Delimiter
        }

    }
    End {}

}

用法:

$Data = @(
    [PSCustomObject]@{
        A = $null
        B = Get-Date
        C = $null
    }
    [PSCustomObject]@{
        A = 1
        B = Get-Date
        C = 'Lorem'
    }
    [PSCustomObject]@{
        A = 2
        B = Get-Date
        C = 'Ipsum'
    }
    [PSCustomObject]@{
        A = 3
        B = $null
        C = 'Lorem Ipsum'
    }
)

# with headers
PS> ConvertTo-Delimited $Data
A|B|C
1|7/17/19 9:07:23 PM|Lorem
2|7/17/19 9:07:23 PM|Ipsum
||

# without headers
PS> ConvertTo-Delimited $Data -ExcludeHeader
1|7/17/19 9:08:19 PM|Lorem
2|7/17/19 9:08:19 PM|Ipsum
||

答案 9 :(得分:0)

嗯,我在Mac上安装了Powershell 7预览版1,而Export-Csv具有-UseQuotes选项,您可以将其设置为Never。 :)

答案 10 :(得分:0)

JPBlanc答案的一个稍作修改的变体:

我有一个现有的csv文件,如下所示:

001,002,003
004,005,006

我只想将第一列和第三列导出到新的csv文件。而且可以肯定的是,我不需要任何引号;-) 可以这样完成:

Import-Csv -Path .\source.csv -Delimiter ',' -Header A,B,C | select A,C | ConvertTo-Csv -NoTypeInformation -Delimiter ',' | % {$_ -replace '"',''} | Out-File -Encoding utf8 .\target.csv

答案 11 :(得分:0)

找不到类似问题的答案,所以我要发布在这里找到的内容...

对于以管道分隔符导出且字符串限定符不加引号,请使用以下命令:

$objtable | convertto-csv -Delimiter "|" -notypeinformation | select -Skip $headers | % { $_ -replace '"\|"', "|"} | % { $_ -replace '""', '"'} | % { $_ -replace "^`"",''} | % { $_ -replace "`"$",''} | out-file "$OutputPath$filename" -fo -en ascii

这是我唯一能处理文本中引号和逗号的内容;尤其是在文本字段的开头或结尾处,引号和逗号彼此相邻。

答案 12 :(得分:0)

此函数从管道中获取一个Powershell csv对象,并输出类似convertto-csv的输出,但不添加引号(除非需要)。

function convertto-unquotedcsv {
    param([Parameter(ValueFromPipeline=$true)]$csv, $delimiter=',', [switch]$noheader=$false)
    begin {
      $NeedQuotesRex = "($([regex]::escape($delimiter))|[\n\r\t])"
      if ($noheader) { $names = @($true) } else { $names = @($false) }
    } 
    process {
      $psop = $_.psobject.properties
      if (-not $names) {
        $names = $psop.name | % {if ($_ -match $NeedQuotesRex) {'"' + $_ + '"'} else {$_}}
        $names -join $delimiter   # unquoted csv header
      }
      $values = $psop.value | % {if ($_ -match $NeedQuotesRex) {'"' + $_ + '"'} else {$_}}
      $values -join $delimiter    # unquoted csv line
    } 
    end {
    }
}

$ names获取一个数组的音符属性名称,而$ values获取一个数组的音符属性值。采取了特殊的步骤来输出标题。该处理块一次获取一个csv对象。

这里是试运行

$delimiter = ','; $csvData = @"
id,string,notes,"points per 1,000",number
4,"a delimiter$delimiter is in here,","test data 3",1,348
5,"a comma, is in here,","test data 4`r`nwith a newline",0.5,347
6,hello world2.,classic,"3,000",123
"@

$csvdata | convertfrom-csv | sort number | convertto-unquotedcsv -delimiter $delimiter

id,string,notes,"points per 1,000",number
6,hello world2.,classic,"3,000",123
5,"a comma, is in here,","test data 4
with a newline",0.5,347
4,"a delimiter, is in here,",test data 3,1,348

答案 13 :(得分:0)

这是另一种方法:

Get-Process | ConvertTo-Csv -NoTypeInformation -Delimiter "," | 
    foreach { $_ -replace '^"|"$|"(?=,)|(?<=,)"','' }

这会在每行中用空字符串替换匹配项。分解上面的正则表达式:

  • |就像一个OR,用于组合以下4个子正则表达式
  • ^"匹配行首的引号
  • "$匹配行尾的引号
  • "(?=,)匹配引号,后跟逗号
  • (?<=,)"匹配引号后面紧跟一个逗号