Слияние двух CSV, а затем переупорядочение столбцов на выходе - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть первый CSV:

Server,Info  
server1,item1
server1,item1

и этот 2-й CSV:

Server,Info  
server2,item2
server2,item2

И я пытаюсь получить этот вывод:

Server,Server,Info,Info
server1,server2,item1,item2
server1,server2,item1,item2

Как видите, проблема в том, что заголовки двух CSV имеют одинаковые имена, что вызывает проблему, если я разбираю их по объектам и перебираю ключи.

Поэтому я пытаюсь объединить их, а затем переупорядочить ихкак строки, но я не могу понять, как это сделать в последнем цикле for:

$file1 = Get-Content ".\Powershell test\A.csv"
$file2 = Get-Content ".\Powershell test\B.csv"

$content = for ($i = 0; $i -lt $file1.Length; $i++) {
    '{0},{1}' -f $file1[$i].Trim(), $file2[$i].Trim()
}

$content | Out-File  ".\Powershell test\merged.csv"

$firstFileParsed = Import-Csv -Path ".\Powershell test\B.csv"
$secondFileParsed = Import-Csv -Path ".\Powershell test\B.csv"

$secondFilePath =  ".\Powershell test\B.csv"
$contentOf2ndFile = Get-Content $secondFilePath

$csvColumnNames = (Get-Content '.\Powershell test\B.csv' |
                  Select-Object -First 1).Split(",")

$newColumns = @()

foreach($header in $csvColumnNames) {
    $newColumns += $header
}

$newColumns = $newColumns -join ","
$contentOf2ndFile[0] = $newColumns
$contentOf2ndFile | Out-File ".\Powershell test\temp.csv"

$tempObject = Import-Csv -Path ".\Powershell test\temp.csv"
$tempFile = Get-Content ".\Powershell test\temp.csv"

$array = @()
$tempArr = @()

for ($i = 0; $i -lt $file1.Length; $i++) {
    $tempArr1 = $file1[$i] -split ","
    $tempArr2 = $tempFile[$i] -split ","

    for ($j = 0; $j -lt $tempArr1.Length; $j++) {
        $tempArr += $tempArr1[$j] +  "," + $tempArr2[$j]
        $tempArr
    }

    $array += $tempArr
}

$array | Out-File '.\Powershell test\merged.csv'

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Похоже, что было несколько случаев, когда вместо слияния они различали несвязанные ключи свойств, я добавил новую функцию.Параметр -Unify (формально / псевдоним -Merge) для командлета Join-Object теперь принимает одну или две динамические клавиши для различения несвязанных пар столбцов в объединении.

Параметр -Unify (псевдоним -Merge) определяет, как объединить левый и правый объект по отношению к несвязанным общим свойствам.Общие свойства могут различаться (<String>[,<String>]) или объединяться (<ScriptBlock>).По умолчанию несвязанные общие свойства будут объединены с использованием выражения: {$LeftOrVoid.$_, $RightOrVoid.$_}

<String>[,<String>] Если значение не является ScriptBlock, предполагается строковый массив с одним или двумя элементами, определяющими слева иправильный формат ключа.Если элемент содержит звездочки (*), звездочки будут заменены именем свойства, в противном случае элемент будет использоваться для добавления префикса имени свойства.

Примечание. Последовательный номер будет автоматически добавлен кобщее имя свойства, если оно уже используется.

...

Пример:

$Csv1 = ConvertFrom-Csv 'Server,Info
server1,item1
server1,item1'

$Csv2 = ConvertFrom-Csv 'Server,Info
server2,item2
server2,item2'

$Csv1 | Join $Csv2 -Unify *1, *2

Результат:

Server1 Server2 Info1 Info2
------- ------- ----- -----
server1 server2 item1 item2
server1 server2 item1 item2
0 голосов
/ 26 февраля 2019

То, что вы предлагаете, не очень полезно или даже действительно CSV.ИМХО только два результата будут иметь смысл:

Это:

Server1,Info1,Server2,Info2
server1,item1,server2,item2
server1,item1,server2,item2

Или это:

Server,Info
server1,item1
server1,item1
server2,item2
server2,item2

Первый подход:

$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"

$merged = for($i = 0; $i -lt $csv1.Count; $i++) {
    $new = new-object psobject
    $entry1 = $csv1[$i]
    $entry1 | Get-Member -Type NoteProperty | foreach {
        Add-Member -InputObject $new -MemberType NoteProperty -Name ($_.Name + "1") -Value $entry1.($_.Name)
    }
    $entry2 = $csv2[$i]
    $entry2 | Get-Member -Type NoteProperty | foreach {
        Add-Member -InputObject $new -MemberType NoteProperty -Name ($_.Name + "2") -Value $entry2.($_.Name)
    }
    $new
}

$merged | Export-Csv ".\Powershell test\merged.csv"

Второйподход:

$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"

$merged = $csv1 + $csv2

$merged | Export-Csv ".\Powershell test\merged.csv"

ОБНОВЛЕНИЕ

Если вы хотите точно выводить данные (и файлы наверняка имеют одинаковые заголовки и количество строк), вы можете использовать уникальныеСначала заголовки, а затем просто переименуйте их позже:

$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"
$merged = for($i = 0; $i -lt $csv1.Count; $i++) {
    $new = New-Object PSObject
    ("Server", "Info") | foreach {
        Add-Member -InputObject $new -MemberType NoteProperty -Name ($_ + "1") -Value $csv1[$i].$_
        Add-Member -InputObject $new -MemberType NoteProperty -Name ($_ + "2") -Value $csv2[$i].$_
    }
    $new
}
$header = $true
$merged | ConvertTo-Csv -NoTypeInformation | foreach {
    if ($header) {
        $header = $false
        # remove the numbers from the headers
        $_ -replace "\d", ""
    }
    else { $_ }
} | Out-File ".\Powershell test\merged.csv"

Пояснения:

Count доступно в Powershell для всех коллекций и безопаснее, чем Lengthкоторый является свойством только массивов.Но в этом случае оба должны работать.

В цикле создается новый пустой объект (с New-Object), а затем заполняется путем добавления членов проанализированных объектов CSV (с Add-Member).Счетчик добавляется к именам свойств, чтобы сделать их уникальными.

Коллекция этих объектов ($merged) затем конвертируется в CSV, числа в строке заголовка удаляются и все сохраняется в файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...