2016-09-22 2 views
3

Как сделать Inner-Join или что-то a Cross-Join в PowerShell или PowerCLI?Inner Присоединиться к PowerShell (без SQL)

Даже несмотря на то, что я новый для PowerCLI/PowerShell, у меня есть базовое понимание, но они практически потратили 2 дня, пытаясь понять это, проходя через многочисленные документы и блоги безрезультатно.

Все, что я действительно хочу знать, если после ввода моей команды

Get-Content File.txt 

и получения:

Output1 or Table1 is 

Name: Abc 
Group: Bad 
Policy: Great 

Name: redi 
Group: Good 
Policy: MAD 

etc. etc.

100s из них, и, очевидно, больше, чем просто 3-х элементов имени, групп, Политика каждого.


Table2/Output2 

Name: Abc 
Limit: 10 
used: 5 

Name: redi 
Limit: 20 
used: 1 

etc. etc.

100s из них.


и как еще 13 из этих таблиц текстовых файлов, все с «именем» являются уникальными.

Как я могу объединить его в один вывод в конце, используя имя со всеми остальными элементами?

Моя самая очевидная мысль была чем-то вроде объединения, даже если мне приходилось делать это по одному за раз, но даже я не могу понять, как это сделать.

Есть ли все-таки сделать это в PowerShell без меня, чтобы войти в Python или SQL?

Если да, существует метод, который может комбинировать поля в местах, где он равен нулю?

Если его не ясно, какой тип результата я надеюсь на это будет выглядеть что-то похожее на это:

Name: Abc 
Group: Bad 
Policy: Great 
Limit: 10 
used: 5 


Name: redi 
Group: Good 
Policy: MAD 
Limit: 20 
used: 1

ответ

0

Так что я нашел ответ, который был более подходящим и использует Join-Object, который был определен ниже:

вы можете получить к нему доступ по адресу https://github.com/RamblingCookieMonster/PowerShell/blob/master/Join-Object.ps1

Все, что я должен был сделать определение моих выходов в $ A и $ B и $ C и так далее, и только

$Join1= Join-Object -Left $A -Right $B -LeftJoinProperty Name - RightJoinProperty Name 

составил $ Join2 затем 3 так далее, пока я не получил все это сделано

$Join2 = Join-Object -Left $Join1 -Right $C -LeftJoinProperty Name -RightJoinProperty Name 

$Join3 = Join-Object -Left $Join2 -Right $D -LeftJoinProperty Name -RightJoinProperty Name 

$Join4 = Join-Object -Left $Join3 -Right $E -LeftJoinProperty Name -RightJoinProperty Name 

пока я не получил все это сделано

2

Вы можете использовать простой цикл присоединиться к следующим образом:

$table1 = [pscustomobject]@{Name='Abc';Group='Bad';Policy='Great'},[pscustomobject]@{Name='redi';Group='Good ';Policy='MAD'} 
$table2 = [pscustomobject]@{Name='Abc';Limit=10;used=5},[pscustomobject]@{Name='redi';Limit=20;used=1} 

$table1 | % { 
       foreach ($t2 in $table2) { 
        if ($_.Name -eq $t2.Name) { 
         [pscustomobject]@{Name=$_.Name;Group=$_.Group;Policy=$_.Policy;Limit=$t2.Limit;Used=$t2.Used} 
        } 
       } 
      } 

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

$hashed = $table1 | group Name -AsHashTable 
$table2 | % { 
    $matched = $hashed[$_.Name] 
    if ($matched) { 
     [pscustomobject]@{Name=$matched.Name;Group=$matched.Group;Policy=$matched.Policy;Limit=$_.Limit;Used=$_.Used} 
    } 
} 

Вы также можете использовать общее решение и d оберните его в функцию. Он соответствует записи их имен свойств:

function Join-Records($tab1, $tab2){ 
    $prop1 = $tab1 | select -First 1 | % {$_.PSObject.Properties.Name} #properties from t1 
    $prop2 = $tab2 | select -First 1 | % {$_.PSObject.Properties.Name} #properties from t2 
    $join = $prop1 | ? {$prop2 -Contains $_} 
    $unique1 = $prop1 | ?{ $join -notcontains $_} 
    $unique2 = $prop2 | ?{ $join -notcontains $_} 


    if ($join) { 
     $tab1 | % { 
      $t1 = $_ 
      $tab2 | % { 
       $t2 = $_ 
       foreach ($prop in $join) { 
        if (!$t1.$prop.Equals($t2.$prop)) { return; } 
       } 
       $result = @{}     
       $join | % { $result.Add($_,$t1.$_) } 
       $unique1 | % { $result.Add($_,$t1.$_) } 
       $unique2 | % { $result.Add($_,$t2.$_) } 
       [PSCustomObject]$result 
      } 
     } 
    } 
} 

$table1 = [pscustomobject]@{Name='Abc';Group='Bad';Policy='Great'}, 
    [pscustomobject]@{Name='redi';Group='Good ';Policy='MAD'}, 
    [pscustomobject]@{Name='Not joined';Group='Very bad';Policy='Great'} 
$table2 = [pscustomobject]@{Name='Abc';Limit=10;used=5}, 
    [pscustomobject]@{Name='redi';Limit=20;used=1}, 
    [pscustomobject]@{Name='redi';Limit=20;used=2} 

#name is only common property, records joined by name 
Join-Records $table1 $table2 

#example2 
$test1 = [pscustomobject]@{A=1;B=1;C='R1'}, 
    [pscustomobject]@{A=1;B=2;C='R2'}, 
    [pscustomobject]@{A=2;B=2;C='R3'} 

$test2 = [pscustomobject]@{A=1;B=1;D='R4'}, 
    [pscustomobject]@{A=3;B=2;D='R5'}, 
    [pscustomobject]@{A=4;B=2;D='R6'} 

Join-Records $test1 $test2 #joined by two common columns - A and B 

Вы можете также каскад вызовов:

$test1 = [pscustomobject]@{A=1;B=1;C='R1'}, 
    [pscustomobject]@{A=1;B=2;C='R2'}, 
    [pscustomobject]@{A=2;B=2;C='R3'} 

$test2 = [pscustomobject]@{A=1;B=1;D='R4'}, 
    [pscustomobject]@{A=3;B=2;D='R5'}, 
    [pscustomobject]@{A=4;B=2;D='R6'} 

$test3 = [pscustomobject]@{B=1;E='R7'}, 
    [pscustomobject]@{B=2;E='R8'}, 
    [pscustomobject]@{B=3;E='R9'} 

#first join by common A and B, then join result by common B 
Join-Records (Join-Records $test1 $test2) $test3 
+0

Выполняет ли это задание, но я добавил более общее решение :-) –

+0

Спасибо ... , но я удивлен, если мне нужно набрать мой длинный список пар значений ключа? ..... будет иметь $ table1 = Get-Content file1.txt | Выбрать имя и т. д. и иметь таблицы $ table2 и 3 и т. д. будет работать в качестве замены вашего выше $ table1 с помощью [pscustomobject] и пары значений ключа ..... Также это можно сделать с более чем двумя таблицами? – AdilZ

+0

Добавлен еще один пример. –

2

Paweł Dyl provided you a solution на основе ваших двух таблиц. Однако вам, вероятно, потребуется общее решение, в котором вам не нужно указывать каждое свойство по имени самостоятельно.


Я бы объединил каждую таблицу в массив. Группируйте таблицы в свойстве Name с помощью командлета Group-Object.Итерации по каждой группе и создать PSObject используя свойства:

$table1 = [PSCustomObject]@{ Name = 'Abc'; Group = 'Bad'; Policy = 'Great'}, [PSCustomObject]@{ Name = 'redi'; Group = 'Good'; Policy = 'MAD'} 
$table2 = [PSCustomObject]@{ Name = 'Abc'; Limit = '10'; used = '5'}, [PSCustomObject]@{ Name = 'redi'; Limit = '20'; used = '1'} 

$allTables = $table1 + $table2 

$allTables | group Name | Foreach { 
    $properties = @{} 
    $_.Group | Foreach { 
     $_.PsObject.Properties | Where Name -ne 'Name' | Foreach { 
      $properties += @{ 
       "$($_.Name)" = "$($_.Value)" 
      } 
     } 
    } 
    $properties += @{Name = $_.Name} 
    New-Object PSObject –Property $properties 
} 

Выход:

Group : Bad 
Policy : Great 
Name : Abc 
Limit : 10 
used : 5 

Group : Good 
Policy : MAD 
Name : redi 
Limit : 20 
used : 1 
+1

Хорошо, поддержал :) Я также добавил не-общее хэш-соединение. –

+0

Вам, вероятно, придется разбирать текстовые файлы - вы можете начать другой вопрос, если вы застряли на нем. Вы можете использовать '| Select-Object name, Group, ... ', чтобы определить порядок выбора и получить имя всегда сверху. Пожалуйста, подумайте о принятии ответа. –

+0

Спасибо Я думаю, что только подтвердив, что file.txt, если я могу Get-контент и добавьте в ваш код, начинающийся с $ table1 = и просто настроить его достаточно, чтобы соответствовать моей таблице спецификации Потому что я не хочу просто введите все разные пары значений ключа, так как он победит цель и не задержит слово, когда добавляется другое «имя» во весь список, и я снова запускаю код – AdilZ

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