Mohammad Nadeem
Mohammad Nadeem

Reputation: 9392

ConvertTo-Csv Output without quotes

I am using ConvertTo-Csv to get comma separated output

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

It outputs like:

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

However I would like to get output without quotes, like

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

Upvotes: 30

Views: 109302

Answers (14)

js2010
js2010

Reputation: 27428

Hmm, I have Powershell 7 preview 1 on my mac, and Export-Csv has a -UseQuotes option that you can set to AsNeeded. :)

Upvotes: 29

ricab
ricab

Reputation: 2802

Here's another approach:

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

This replaces matches with the empty string, in each line. Breaking down the regex above:

  • | is like an OR, used to unite the following 4 sub-regexes
  • ^" matches quotes in the beginning of the line
  • "$ matches quotes in the end of the line
  • "(?=,) matches quotes that are immediately followed by a comma
  • (?<=,)" matches quotes that are immediately preceded by a comma

Upvotes: 2

Greek2me
Greek2me

Reputation: 1

This function takes a powershell csv object from the pipeline and outputs like convertto-csv but without adding quotes (unless needed).

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 gets an array of noteproperty names and $values gets an array of notepropery values. It took that special step to output the header. The process block gets the csv object one piece at a time.

Here is a test run

$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

Upvotes: 0

VenerableAgents
VenerableAgents

Reputation: 656

Couldn't find an answer to a similar question so I'm posting what I've found here...

For exporting as Pipe Delimited with No Quotes for string qualifiers, use the following:

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

This was the only thing I could come up with that could handle quotes and commas within the text; especially things like a quote and comma next to each other at the beginning or ending of a text field.

Upvotes: 0

Jan K&#246;hler
Jan K&#246;hler

Reputation: 6030

A slightly modified variant of JPBlanc's answer:

I had an existing csv file which looked like this:

001,002,003
004,005,006

I wanted to export only the first and third column to a new csv file. And for sure I didn't want any quotes ;-) It can be done like this:

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

Upvotes: 0

Tiago Peres
Tiago Peres

Reputation: 15431

Once the file is generated, you can run

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

Upvotes: 7

Fred
Fred

Reputation: 111

I was working on a table today and thought about this very question as I was previewing the CSV file in notepad and decided to see what others had come up with. It seems many have over-complicated the solution.
Here's a real simple way to remove the quote marks from a CSV file generated by the Export-Csv cmdlet in PowerShell.

Create a TEST.csv file with the following data.

"ID","Name","State"
"5","Stephanie","Arizona"
"4","Melanie","Oregon"
"2","Katie","Texas"
"8","Steve","Idaho"
"9","Dolly","Tennessee"

Save As: TEST.csv

Store file contents in a $Test variable
$Test = Get-Content .\TEST.csv

Load $Test variable to see results of the get-content cmdlet
$Test

Load $Test variable again and replace all ( "," ) with a comma, then trim start and end by removing each quote mark

$Test.Replace('","',",").TrimStart('"').TrimEnd('"')

Save/Replace TEST.csv file

$Test.Replace('","',",").TrimStart('"').TrimEnd('"') | Out-File .\TEST.csv -Force -Confirm:$false

Test new file Output with Import-Csv and Get-Content:

Import-Csv .\TEST.csv
Get-Content .\TEST.csv

To Sum it all up, the work can be done with 2 lines of code

$Test = Get-Content .\TEST.csv
$Test.Replace('","',",").TrimStart('"').TrimEnd('"') | Out-File .\TEST.csv -Force -Confirm:$false

Upvotes: 11

craig
craig

Reputation: 26262

I wrote this for my needs:

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 {}

}

Usage:

$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
||

Upvotes: 2

Kory Gill
Kory Gill

Reputation: 7153

I ran into this issue, found this question, but was not satisfied with the answers because they all seem to suffer if the data you are using contains a delimiter, which should remain quoted. Getting rid of the unneeded double quotes is a good thing.

The solution below appears to solve this issue for a general case, and for all variants that would cause issues.

I found this answer elsewhere, Removing quotes from CSV created by PowerShell, and have used it to code up an example answer for the SO community.

Attribution: Credit for the regex, goes 100% to Russ Loski.

Code in a Function, 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
}

Test Code

$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

Test Output

---- 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

Upvotes: 10

LCC
LCC

Reputation: 948

Depending on how pathological (or "full-featured") your CSV data is, one of the posted solutions will already work.

The solution posted by Kory Gill is almost perfect - the only issue remaining is that quotes are removed also for cells containing the line separator \r\n, which is causing issues in many tools.

The solution is adding a newline to the character class expression:

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

Upvotes: 3

kproth
kproth

Reputation: 11

I found that Kory's answer didn't work for the case where the original string included more than one blank field in a row. I.e. "ABC",,"0" was fine but "ABC",,,"0" wasn't handled properly. It stopped replacing quotes after the ",,,". I fixed it by adding "|(?<output>)" near the end of the first parameter, like this:

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

Upvotes: 1

bwerks
bwerks

Reputation: 8971

This is pretty similar to the accepted answer but it helps to prevent unwanted removal of "real" quotes.

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

This will do the following:

  • Remove quotes that begin a line
  • Remove quotes that end a line
  • Replace quotes that wrap a delimiter with the delimiter alone.

Therefore, the only way this would go wrong is if one of the values actually contained not only quotes, but specifically a quote-delimiter-quote sequence, which hopefully should be pretty uncommon.

Upvotes: 10

JPBlanc
JPBlanc

Reputation: 72610

Here is a way to remove the quotes

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

But it has a serious drawback if one of the item contains a " it will be removed !

Upvotes: 28

ravikanth
ravikanth

Reputation: 25800

I haven't spent much time looking for removing the quotes. But, here is a workaround.

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

This is a quick workaround and there may be a better way to do this.

Upvotes: 0

Related Questions