背景
我必須運行SqlCmd并Bcp獲取 Sql 表的輸出。有更好的方法,但這是我可以使用的。
首先,我運行SqlCmd以獲取表標題并保存到C:\headers.csv.
SqlCmd -S Server -d Database -Q "set nocount on; select top 0 * from TableName;" -o "C:\headers.csv" -s "," -W
接下來,我運行Bcp以從表中獲取資料并保存到C:\data.csv.
Bcp TableName out "C:\data.csv" -S Server -d Database -T -t , -c
我最終得到兩個檔案headers.csv和data.csv. 我需要將 的內容附加headers.csv到data.csv.
我的嘗試
令人討厭的是,SqlCmd在標題后添加一行連字符。我去掉那條線:
Get-Content -Path "C:\headers.csv" -TotalCount 1 | Out-File -FilePath "C:\final-output.csv" -Force
這就是我想出的對兩個檔案進行最終“連接”的方法:
[System.IO.File]::AppendAllLines("C:\final-output.csv",[System.IO.File]::ReadLines("C:\data.csv"))
我在 Server 2016 上運行。使用 PowerShell 是否有更快的方法來讀取或寫入final-output.csv?
uj5u.com熱心網友回復:
這不是內置支持的操作,通常在檔案末尾進行追加。我知道您唯一的選擇是讀入當前內容,在位置 0 插入新內容,然后重新寫入檔案。為此,我們將使用 aList來幫助完成此程序并防止字串/陣列連接:
注意:此示例假定目標檔案編碼為 UTF8。.NET 無法知道當前檔案是用什么編碼撰寫的,因此您需要提前知道這一點并相應地更改編碼。查看前面鏈接中的派生型別以了解 PowerShell/.NET 支持的開箱即用編碼。
# $newContent should be what you want to append to the start of the existing file
# If $newContent is already an array of text lines then you do not need to worry about
# splitting on `[Environment]::NewLine` and you can pass $newContent in directly.
$newContent = [System.Generic.Collections.List[string]]::new(( $newContent -split [System.Environment]::NewLine ))
# $filePath should be the file you want to append to the beginning of
$newContent.Add(( Get-Content $filePath ))
# Write back out to file, overwriting the existing content ($newContent should have it all)
$newContent | Out-File -Encoding UTF8 -Force $filePath
不幸的是,這不會特別有效,盡管使用List[string]可以防止對現有內容進行不必要的重復,這應該會有所幫助,特別是如果它是一個較大的檔案。缺點是您必須在最后讀入所有現有內容(或者先讀取檔案內容并在 index 處插入新內容0,盡管本示例沒有這樣做),因此必須重新讀取整個檔案書面。正如我在開頭提到的,直接寫入檔案的開頭而不是結尾是不支持的操作。
uj5u.com熱心網友回復:
我對這兩個命令的作業原理了解不多,所以如果我錯了,請糾正我。
假設如果我們 removeSqlCmd回傳一個array標準輸出-o "C:\headers.csv",我們可以像這樣存盤標頭:
$headers = SqlCmd -S Server -d Database -Q "set nocount on; select top 0 * from TableName;" -s "," -W
$headers = $headers[0]
如果它不回傳一個陣列而實際上回傳一個多行字串,那么這應該有效:
$headers = SqlCmd -S Server -d Database -Q "set nocount on; select top 0 * from TableName;" -s "," -W
$headers = $headers -split '\r?\n' | Select-Object -First 1
然后,假設如果我們out "C:\data.csv"從中洗掉Bcp將表的內容回傳到標準輸出,我們可以將結果存盤到$data變數中:
$data = Bcp TableName -S Server -d Database -T -t , -c
現在你應該能夠做這樣的事情來合并兩個變數:
$headers, $data | Out-File path\to\csv.csv
一個簡單的例子:
# This would be a multi-line string
$headers = @'
col1,col2,col3
--------------
'@
$headers = $headers -split '\r?\n' | Select-Object -First 1
# Then something random for $data
$data = 0..5 | ForEach-Object { $x = Get-Random; "$x,$x,$x" }
# Lastly:
PS \> $headers, $data
col1,col2,col3
1975011385,1975011385,1975011385
858903029,858903029,858903029
1830294256,1830294256,1830294256
1252960811,1252960811,1252960811
1400092566,1400092566,1400092566
1412627916,1412627916,1412627916
# If we pass this to Out-File it should look exactly as we're seeing it on the console
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/339462.html
上一篇:?Weka中的值處理
