2016-07-19 2 views
-1

Я хочу объединить два CSV-файла, которые имеют один и тот же заголовок в один файл CSV. У меня есть два таких файла, как показано ниже, т.е. DevData.csv и ProdData.csv с таким же cfname и разные ID секСлить два файла CSV

 ID     cfname 
    -------------------- ----------------------------------- 
        10201 Risk ID 
        10202 Issue ID 
        10203 Dependency ID 
        10204 Server ID 
        10205 Parent Application ID 
        10206 Application Service ID 
        10207 Application Supportability 
        10208 Application Compatibility 
        10300 Application Status 
        10301 Contact ID Type 2 
        10302 Contact ID Type 3 
        10303 Contact ID Type 4 
        10304 Business Service Manager 
        10308 Server Location Name: 
        10309 Rack Position: 
        10310 Rack Number: 
        10311 Data Centre 
        10312 Server Group 
(14 rows affected)

Я хочу создать новый CSV в следующем формате:

DevID    ProdID cfname 
-------------------- ------ ----------------------------------- 
       10201 201 Risk ID 
       10202 202 Issue ID 
       10203 203 Dependency ID 
       10204 204 Server ID 
       10205 205 Parent Application ID 
       10206 206 Application Service ID 
       10207 207 Application Supportability 
       10208 208 Application Compatibility 
       10300 209 Application Status 
       10301 210 Contact ID Type 2 
       10302 211 Contact ID Type 3 
       10303 212 Contact ID Type 4 
       10304 213 Business Service Manager 
       10308 214 Server Location Name:

Ниже приведен мой текущий код , но он экспортирует данные первого файла и под ним данные следующего файла.

function Merge-CSVFiles { 
    [cmdletbinding()] 
    param(
     [string[]]$CSVFiles 
    ) 

    $Output = @(); 
    foreach ($CSV in $CSVFiles) { 
     if (Test-Path $CSV) { 
      $FileName = [System.IO.Path]::GetFileName($CSV) 
      $temp = Import-CSV -Path $CSV | 
        select ID, cfname, ID, cfname, @{Expression={$FileName}} 
      $Output += $temp 
     } else { 
      Write-Warning "$CSV : No such file found" 
     } 
    } 
    $Output | Export-Csv -Path $OutputFile -NoTypeInformation 
    Write-Output "$OutputFile successfully created" 
} 

Merge-CSVFiles -CSVFiles "C:\Users\ECSAdmin\Desktop\Proddata.csv", "C:\Users\ECSAdmin\Desktop\Devdata.csv" -OutputFile "C:\Users\ECSAdmin\Desktop\Mergedata.csv" 
+1

"* два файла csv, которые имеют одинаковый заголовок *" - но 'ID, cfname' и' DevID, ProdID, cfname' не совпадают? – TessellatingHeckler

+0

DevID и ProdID будут представлены в выходном файле CSV. Я выполнил тот же запрос в разработке (создает Devdata.csv) и production (создает Proddata.csv) db, которые создают одинаковый вывод с другим ID.Также я хочу объединить эти два файла с ProdID, DevID и cfname в качестве заголовков в конечном выходном файле csv. – Abhaya

+0

Вам нужно добавить заголовок. 'Import-CSV -path ".csv" -header DevID, ProdID, Cfname' и объединить два CSV ' $ слился = $ csv1 + $ csv2 $ слиты | Select -Property * -Unique' – DisplayName

ответ

0

You может сделать вложенный цикл Еогеасп над двумя наборами, но два избежать времени выполнения растет экспоненциально по отношению к размеру входного сигнала, лучшей стратегией было бы загрузить один набор в хэш-таблицу (с помощью общее свойство cfname как ключ), а затем цикл над другим и сростить два:

$DevData = @' 
ID,cfname 
10201,Risk ID 
10202,Issue ID 
10203,Dependency ID 
10204,Server ID 
10205,Parent Application ID 
10206,Application Service ID 
10207,Application Supportability 
10208,Application Compatibility 
10300,Application Status 
10301,Contact ID Type 2 
10302,Contact ID Type 3 
10303,Contact ID Type 4 
10304,Business Service Manager 
10308,Server Location Name: 
10309,Rack Position: 
10310,Rack Number: 
10311,Data Centre 
10312,Server Group 
'@ |ConvertFrom-Csv 

$ProdData = @' 
ID,cfname 
201,Risk ID 
202,Issue ID 
203,Dependency ID 
204,Server ID 
205,Parent Application ID 
206,Application Service ID 
207,Application Supportability 
208,Application Compatibility 
209,Application Status 
210,Contact ID Type 2 
211,Contact ID Type 3 
212,Contact ID Type 4 
213,Business Service Manager 
214,Server Location Name: 
'@ |ConvertFrom-Csv 

# throw one set into a hashtable 
# we can use this as a lookup table for the other set 
$ProdTable = @{} 
foreach($line in $ProdData){ 
    $ProdTable[$line.cfname] = $line.ID 
} 

# Output the DevData with the appropriate ProdData value 
$DevData |Select-Object @{Label='DevID';Expression={$_.ID}},@{Label='ProdID';Expression={$ProdTable[$_.cfname]}},cfname |Export-Csv .\new.csv -NoTypeInformation 
+0

Спасибо @Mathias Это работает отлично, если я скопирую данные CSV в переменные, как вы уже упоминали, но не при выполнении импорта-CSV. Я не могу скопировать данные вставить все время, есть ли способ достичь того же, используя import-csv? – Abhaya

+0

@Supriya Если файлы csv имеют то же содержимое, что и строки в моем примере, вывод из 'Import-Csv' будет таким же, как вы видите из' ConvertFrom-Csv' выше –

0

Вы можете попробовать этот простой конвейер команд:

Out-file -FilePath '.\csv3.csv' -InputObject "ProdID,ID,cfname"; ForEach($CFName In $Csv1) { $Csv2.Where({$_.cfname -eq $CFName.cfname}) | %{ "$($_.ProdID),$($CFName.ID),$($_.cfName)" } | Out-File .\csv3.csv -Append} 

Где я предполагал, что Csv1.csv - это первый файл с столбцами ID и cfname, а второй файл Csv2.csv имеет столбцы ProdID и cfname. Это даст третий csv3.csv файл с содержимым слившихся

0

Поскольку вы экспорта данных из SQL Server с sqlcmd необходимо добавить параметры -W и -s",", чтобы ваша команда создать фактический вывод CSV:

sqlcmd -S server -d db -E -Q "query" -W -s"," -o output.csv 

После того как вы фактические CSV-файлы можно обработать их следующим образом:

# create a hashtable from the second CSV, so you can look up IDs by the 
# values in the "cfname" column 
$proddata = @{} 
Import-Csv 'C:\path\to\ProdData.csv' | ForEach-Object { 
    $proddata[$_.cfname] = $_.ID 
} 

Import-Csv 'C:\path\to\DevData.csv' | 
    Select-Object @{n='DevID';e={$_.ID}}, 
       @{n='ProdID';e={$proddata[$_.cfname}}, cfname | 
    Export-Csv 'C:\path\to\merged.csv' 

Это предположит, что ваш ProdData.csv содержит только cfname значения, которые также появляются в DevData.csv, и что ваши значения cfname уникальны как минимум в ProdData.csv. Двухстороннее слияние сложнее, так как вам нужно проверить ключи whick в $proddata, не существует в DevData.csv и добавьте их соответственно. Если ваши значения cfname не уникальны, вы не сможете выровнять записи.

+0

. Он выводит следующую ошибку на выходе. csv file 'Sqlcmd: '"': Неожиданный аргумент. Войти '-?' для справки. ' – Abhaya

+0

Это выглядит как типографская цитата. Не используйте их в коде. –

+0

Это сработало. Спасибо большое :) – Abhaya

Смежные вопросы