Массив Powershell - объединение в одном месте
У меня есть скрипт, который возвращает следующую информацию
Analog Phones IP Phones Location
------------- --------- --------
0 883 Site1
413 0 Site1
0 4 Site1
0 258 Site2
9 75 Site2
183 0 Site2
Эта информация хранится в массиве $ arrayX
Я пытаюсь выяснить, как получить выход, чтобы показать
Analog Phones IP Phones Location
------------- --------- --------
413 887 Site1
192 333 Site2
Данные, поступающие в массив, не представлены таким образом; У кого-нибудь есть идеи, как этого добиться? Я могу опубликовать весь сценарий, но сейчас это путаница из java, axl и powershell.
В скрипте есть точка, где данные выглядят так
Analog Phones IP Phones Location
------------- --------- --------
413 0 Site1-AGW-DP
0 883 Site1-PHONES-DP
0 4 Site1-PHSRST-DP
Используемые файлы XML выводятся из программы Java Axl. результаты одного из них показаны ниже:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<axl:executeSQLQueryResponse xmlns:axl="http://www.cisco.com/AXL/API/6.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" sequence="1394831301468">
<return>
<row>
<analog_phones>0</analog_phones>
<ip_phones>47</ip_phones>
<devicepool>Site20-PHONES-DP</devicepool>
</row>
<row>
<analog_phones>533</analog_phones>
<ip_phones>0</ip_phones>
<devicepool>Site20-AGW-DP</devicepool>
</row>
<row>
<analog_phones>1</analog_phones>
<ip_phones>689</ip_phones>
<devicepool>Site20-PHSRST-DP</devicepool>
</row>
</return>
</axl:executeSQLQueryResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Скрипт Powershell, начинающийся после бита Java
$files = (Get-ChildItem .\*out.xml).name
foreach ($file in $files){
[xml]$xmlfiles = gc $file
$finalxml += $xmlfiles.envelope.body.executeSQLQueryResponse.return.row
Remove-Item $pwd\$file
}
$outarray = @()
$sitelist = import-csv sites.csv
foreach($item in $finalxml){
if(!$item.devicepool){$sed="BLANK"}
else{$sed=($item.devicepool).substring(0,4)}
$location=($sitelist | where-object {$_.prefix -eq $sed}).Facility
if(!$location){$location=$sed}
$outarray+=New-object psobject -property @{
'Analog Phones' = $item.analog_phones
'IP Phones' = $item.ip_phones
'Location' = $location
}
}
$outarray | Sort-Object 'Analog Phones','IP PHones' -unique | sort-object Location | select-object 'Analog Phones','IP Phones',Location |export-csv $csvout
2 ответа
Примерно так должно работать:
$result = @()
Function getIndex($location)
{
for($j = 0; $j -lt $result.Count; $j++) {
if($result[$j].Location -contains "$location") {
$index=$j
break;
}
}
return $index
}
for ($i=0; $i -lt $outarray.length; $i++) {
$loc=$outarray[$i].Location
$aphones=$outarray[$i].'Analog Phones'
$ipphones=$outarray[$i].'IP Phones'
if(!($result | where-object {$_.Location -eq "$loc"})) {
$result+=New-object psobject -property @{'Location' = "$loc"; 'Analog Phones' = $aphones; 'IP Phones' = $ipphones}
} else {
$index=getIndex($loc)
$result[$index].'Analog Phones' = $result[$index].'Analog Phones' + $aphones
$result[$index].'IP Phones' = $result[$index].'IP Phones' + $ipphones
}
}
$result
$result
вывод:
Analog Phones IP Phones Location
------------- --------- --------
413 887 Site1
192 333 Site2
Вот логика:
Define an empty $result array to store final results
Iterate over $outarray
each time a location is found
if location does not exists in $result then
add full line from $outarray into $result for this location
if location already exists in $result then
retrieve the index for the given location in $result
update Analog Phones number in $result with values from $outarray + $result for the given location (index)
update IP Phones number in $result with values from $outarray + $result for the given location (index)
PS: я не гуру Powershell, поэтому я думаю, getIndex
может быть улучшено. Тем не менее, это сработало для меня на основе вашего исходного кода.
Надеюсь, это поможет!
РЕДАКТИРОВАТЬ
Вот как я интегрировал свой код в ваш:
Сначала я создал $outarray
как вы (я думаю), за исключением того, что я использовал жестко закодированные значения (не анализируя XML-файл):
$outarray = @()
$outarray+=New-object psobject -property @{'Analog Phones' = 0;'IP Phones' = 883;'Location' = "Site1"}
$outarray+=New-object psobject -property @{'Analog Phones' = 413;'IP Phones' = 0;'Location' = "Site1"}
$outarray+=New-object psobject -property @{'Analog Phones' = 0;'IP Phones' = 4;'Location' = "Site1"}
$outarray+=New-object psobject -property @{'Analog Phones' = 0;'IP Phones' = 258;'Location' = "Site2"}
$outarray+=New-object psobject -property @{'Analog Phones' = 9;'IP Phones' = 75;'Location' = "Site2"}
$outarray+=New-object psobject -property @{'Analog Phones' = 183;'IP Phones' = 0;'Location' = "Site2"}
С этого момента мой $outarray
выглядит так:
Analog Phones IP Phones Location
------------- --------- --------
0 883 Site1
413 0 Site1
0 4 Site1
0 258 Site2
9 75 Site2
183 0 Site2
Затем я добавил свой код сразу после вашего export-csv
команда:
$outarray | Sort-Object............
MY CODE HERE
РЕДАКТИРОВАТЬ 2
Я обнаружил проблему с вашим реальным кодом: числа интерпретируются как строки, поэтому их нельзя правильно рассчитать. Вы должны преобразовать их в целые числа:
foreach($item in $finalxml){
...
...
$outarray+=New-object psobject -property @{
'Analog Phones' = [int]$item.analog_phones
'IP Phones' = [int]$item.ip_phones
'Location' = $location
}
}
Судя по всему, вы пытаетесь объединить все результаты в одну запись для каждого сайта? например, - Всего аналоговых телефонов и Всего IP-телефонов в каждом месте.
Если это так, вы должны быть в состоянии перебрать этот массив. Суммируйте аналоговые телефоны и IP-телефоны на сайт, затем используйте эти значения для заполнения нового массива.
Если вы ищете какой-то код, нам нужно знать, как создается массив для построения логики.