Joe*_*Joe 3 powershell export-to-csv
我正在尝试Export-Csv在 PowerShell 脚本中使用不带标头的多个 CSV 文件。我读过一些关于使用该Select-Object -Skip 1技巧的文章,但我还没有让它成功地在我的代码上工作。这是我尝试调用它的方式:
$DataSet.Tables[0] | Select-Object -Skip 1 |
Export-Csv -NoTypeInformation -Path "C:\$($csvname[$i])_$timer.csv"
Run Code Online (Sandbox Code Playgroud)
这是我的完整功能代码:
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
Run Code Online (Sandbox Code Playgroud)
You're misunderstanding how CSVs work in PowerShell. Assume you have a CSV file with the following content:
foo,bar,baz A,1,2 B,3,4
Importing that CSV via Import-Csv will give you 2 objects with the properties foo, bar, and baz filled with the values from one data row each. Using JSON notation the list of objects would look like this:
foo,bar,baz A,1,2 B,3,4
Export-Csv does basically the same, just in reverse. I takes objects as input and writes the values of their properties to the fields of the CSV. The fields are determined by the properties of the first object Export-Csv receives. If one of these properties is missing in a subsequent object a NULL value is written to the respective field. If a subsequent object has additional properties that the first object didn't have they are ignored.
Using Select-Object -Skip 1 with either Import-Csv or Export-Csv is useless, because normally you don't want to skip any of the input or output objects (otherwise you'd lose data).
There are, however, two other cmdlets similar to Import-Csv and Export-Csv that read and write strings rather than files: ConvertFrom-Csv and ConvertTo-Csv. Import-Csv is basically a combination of Get-Content and ConvertFrom-Csv, and Export-Csv a combination of ConvertTo-Csv and Set-Content.
So, where does Select-Object -Skip 1 come into play here? When you convert your object input to CSV via ConvertTo-Csv and skip the first row of the string output, you effectively remove the header line from the output text, something you couldn't do with Export-Csv.
Demonstration:
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"
Pipe that output into Set-Content and you have the headerless CSV files you want.
$DataSet.Tables[0] |
ConvertTo-Csv -NoType |
Select-Object -Skip 1 |
Set-Content "C:\$($csvname[$i])_$timer.csv"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14781 次 |
| 最近记录: |