PowerShell Export-Csv无标题

时间:2017-08-30 15:13:14

标签: powershell export-to-csv

我尝试在PowerShell脚本中使用Export-Csv创建多个没有标头的CSV文件。我已经阅读了一些关于使用Select-Object -Skip 1技巧的帖子,但我还没有成功处理我的代码。以下是我试图称之为:

$DataSet.Tables[0] | Select-Object -Skip 1 |
    Export-Csv -NoTypeInformation -Path "C:\$($csvname[$i])_$timer.csv"

这是我的完整功能代码:

function Run-Query {
    Param([string[]]$queries,[string[]]$csvname)
    Begin {
        $SQLServer = 'myserver'
        $Database = 'mydatabase'
        $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
        $SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
        $timer = (Get-Date -f yyyy-MM-dd)
    } # End Begin
    Process {
        # Loop through each query
        for ($i = 0; $i -lt $queries.Count; $i++) {
            $SqlCmd = New-Object System.Data.SqlClient.SqlCommand

            # Use the current index ($i) to get the query
            $SqlCmd.CommandText = $queries[$i]
            $SqlCmd.Connection = $SqlConnection
            $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
            $SqlAdapter.SelectCommand = $SqlCmd
            $DataSet = New-Object System.Data.DataSet
            $SqlAdapter.Fill($DataSet)

            # Use the current index ($i) to get the sheetname for the CSV
            $DataSet.Tables[0] | Export-Csv -NoTypeInformation -Path "C:\$($csvname[$i])_$timer.csv"
        }
    } # End Process
    End {
        $SqlConnection.Close()
    }
} # End function run-query.

#Entery Query
$queries = @()
$queries += @'
SELECT * FROM table2
'@
$queries += @'
SELECT * FROM table1
'@

#List of CSV file names.
$csvname = @()
$csvname += 'file1'
$csvname += 'file2'
Run-Query -queries $queries -csvname $csvname

2 个答案:

答案 0 :(得分:3)

您误解了CSV在PowerShell中的工作方式。假设您有一个包含以下内容的CSV文件:

foo,bar,baz
A,1,2
B,3,4

通过Import-Csv导入该CSV将为您提供2个对象,其中属性foobarbaz都填充了每个数据行的值。使用JSON表示法对象列表如下所示:

[
    {
        "foo": "A",
        "bar": "1",
        "baz": "2"
    },
    {
        "foo": "B",
        "bar": "3",
        "baz": "4"
    }
]

Export-Csv基本相同,只是相反。我将对象作为输入,并将其属性的值写入CSV的字段。字段由第一个对象Export-Csv接收的属性确定。如果后续对象中缺少其中一个属性,则会将NULL值写入相应的字段。如果后续对象具有第一个对象没有被忽略的附加属性。

Select-Object -Skip 1Import-CsvExport-Csv一起使用是没用的,因为通常你不想跳过任何输入或输出对象(否则你就是&#d; dd丢失数据)。

但是,有两个类似于Import-CsvExport-Csv的其他cmdlet,它们读取和写入字符串而不是文件:ConvertFrom-CsvConvertTo-CsvImport-Csv基本上是Get-ContentConvertFrom-Csv的组合,Export-CsvConvertTo-CsvSet-Content的组合。

那么,Select-Object -Skip 1在哪里发挥作用?当您通过ConvertTo-Csv将对象输入转换为CSV并跳过字符串输出的第一行时,您可以有效地从输出文本中删除标题行,这是Export-Csv无法做到的。

演示:

PS C:\> $data = @()
PS C:\> $data += [PSCustomObject]@{"foo"="A"; "bar"="1"; "baz"="2"}
PS C:\> $data += [PSCustomObject]@{"foo"="B"; "bar"="3"; "baz"="4"}
PS C:\> $data | Format-Table -Auto

foo bar baz
--- --- ---
A   1   2
B   3   4

PS C:\> $data | ConvertTo-Csv -NoType
"foo","bar","baz"
"A","1","2"
"B","3","4"
PS C:\> $data | ConvertTo-Csv -NoType | Select-Object -Skip 1
"A","1","2"
"B","3","4"

将输出管道传输到Set-Content,并且您拥有所需的无头CSV文件。

$DataSet.Tables[0] |
    ConvertTo-Csv -NoType |
    Select-Object -Skip 1 |
    Set-Content "C:\$($csvname[$i])_$timer.csv"

答案 1 :(得分:0)

以下是将CSV输入对象输出为不带标题的制表符分隔数据的一种方法:

function ConvertTo-Tsv {
  param(
    [parameter(ValueFromPipeline=$true)]
    [Object[]] $Object
  )
  process {
    foreach ( $objectItem in $Object ) {
      ($objectItem.PSObject.Properties | Select-Object -ExpandProperty Value) -join "`t"
    }
  }
}

然后您可以执行以下任一操作:

Import-Csv "inputfile.csv" | ConvertTo-Tsv

$data = Import-Csv "inputfile.csv"
ConvertTo-Tsv $data