Сравните столбец IPAddress из csv1 и csv2, и, если совпадения, получите столбец uptime из csv2 - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть 2 csv с данными ниже

csv1:

LNX_HOST_NAME   IPAddress     HOST_ID  SERVER_TYPE
-------------   ---------     -------  -----------
head01.com      10.16.0.11     ABI      WB         
head02.com      10.16.0.12     ABI      WB         
head03.com      10.16.0.14     ABI      WB 

csv2:

Lastboot               IPAddress      SystemUpTime   OSType
--------               ---------      ------------   ------
2/29/2020 3:28:00 AM   10.16.0.10   2698626.75     Unix  
2/29/2020 3:29:00 AM   10.16.0.11   2698560.75     Unix  
2/29/2020 3:34:00 AM   10.16.0.12   2698200.5      Unix  

Необходимо сравнить столбец IP-адрес из обоих csv и return общие записи, подобные приведенным ниже

HOST_NAME       IPAddress     HOST_ID  SERVER_TYPE   SystemUpTime
-------------   ---------     -------  -----------   -------------
head01.com      10.16.0.11     ABI      WB           2698560.75  
head02.com      10.16.0.12     ABI      WB           2698200.5

Нужна помощь для получения логики c для этого. Я написал приведенный ниже код, который дает мне уникальные записи, но не может получить столбец UpTime

$Reference  = Import-Csv -Path "D:\Script\csv2.csv"  | Select-Object -Skip 1
$Difference = Import-Csv -Path "D:\Script\csv1.csv"  | Select-Object -Skip 1


$keys = $Reference | ForEach-Object -MemberName IPAddress | Select-Object -Unique
$DiffVal = $Difference | Where-Object -FilterScript {$keys -Contains $_.IPAddress}

Ответы [ 3 ]

3 голосов
/ 01 апреля 2020

В этом случае я бы использовал Compare-Object , чтобы получить элементы в файлах csv, которые имеют похожие свойства IPAddress, и вывести новые объекты со всеми необходимыми свойствами:

$csv1 = Import-Csv -Path 'D:\csv1.csv'
$csv2 = Import-Csv -Path 'D:\csv2.csv'

$result = Compare-Object -ReferenceObject $csv1 -DifferenceObject $csv2 -Property IPAddress -IncludeEqual -PassThru | 
    Where-Object { $_.SideIndicator -eq '==' } | 
    ForEach-Object {
        $ip = $_.IPAddress
        [PsCustomObject]@{
            'HOST_NAME'    = $_.LNX_HOST_NAME
            'IPAddress'    = $ip
            'HOST_ID'      = $_.HOST_ID
            'SERVER_TYPE'  = $_.SERVER_TYPE
            'SystemUpTime' = ($csv2 | Where-Object {$_.IPAddress -eq $ip}).SystemUpTime
        }
    }

# output on screen
$result | Format-Table -AutoSize

# output to new CSV file
$result | Export-Csv -Path 'D:\Result.csv' -NoTypeInformation

Результат на экране:

HOST_NAME  IPAddress  HOST_ID SERVER_TYPE SystemUpTime
---------  ---------  ------- ----------- ------------
head01.com 10.16.0.11 ABI     WB          2698560.75
head02.com 10.16.0.12 ABI     WB          2698200.5
1 голос
/ 01 апреля 2020

My go - для этого используется следующий подход:

  • Загрузить второй набор данных в хеш-таблицу, используя общее значение в качестве ключа
  • Использовать хеш-таблицу для захвата новые значения столбца с Select-Object:
# Create hashtable containing the desired values from csv2
$SystemUptime = @{}
Import-Csv D:\csv2.csv |ForEach-Object {
    $SystemUptime[$_.IPAddress] = $_.SystemUptime
}

# Filter set based on ip addresses found in the second data set
# Use a calculated property to reference the values in $SystemUptime, then export
Import-Csv D:\csv1.csv |Where-Object {
  $SystemUptime.ContainsKey($_.IPAddress)
} |Select-Object *,@{Name='SystemUptime'; Expression = {$SystemUptime[$_.IPAddress]}} |Export-Csv -Path 'D:\Result.csv' -NoTypeInformation
0 голосов
/ 01 апреля 2020

В случае, если производительность имеет значение, и вы не хотите изобретать велосипед (и не хотите иметь дело с ловушками и проблемами, такими как «, что если в любом списке есть дублирующиеся ключи? »).
Командлет Join-Object (см. Также В Powershell, как лучше объединить две таблицы в одну? ) основан на подходе @ Матиас Р. Йессен упоминается и занимает меньше секунды для объединения двух csv файлов с заданными размерами:

1..2600 | ForEach-Object {
    [pscustomobject]@{HOST_NAME = 'head{0:00}.com' -f ($_ % 100); IPAddress = 10, 16, [math]::floor($_ / 256), ($_ % 256) -Join '.'; HOST_ID = 'ABI'; SERVER_TYPE = 'WB'}
} | Export-Csv .\csv1.csv

1..850 | ForEach-Object {
    [pscustomobject]@{lastboot = Get-Date -f s; IPAddress = 10, 16, [math]::floor(3 * $_ / 256), (3 * $_ % 256) -Join '.'; SystemUpTime = Get-Random 999999; OSType = 'Unix'}
} | Export-Csv .\csv2.csv


Measure-Command {
    Import-Csv .\csv1.csv | Join (Import-Csv .\csv2.csv) -On IPAddress -Property HOST_NAME, IPAddress, HOST_ID, SERVER_TYPE, SystemUpTime | Export-Csv .\Result.Csv
}
  • Примечание1: для соблюдения конвейера PowerShell следует избегать назначения файлов csv переменной (или использовать скобки (...))
  • Примечание 2: Поместить больший файл в левую часть команды Join-Object обычно немного быстрее, чем наоборот.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...