Как я могу сделать foreach выводить два разных файла? - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть эта переменная

$sync_output = Join-Path $syncPATH $CUBE_input

У меня есть цикл foreach:

$i=0
$Destination_Server = @()

foreach($row in $Table | where { $_.cube_name -match $CUBE })
{   
    $i++
    $Destination_Server += $row.Item("query_server")
    write-host " > Query Server $($i):" $Destination_Server[$Destination_Server.length -1]
    $sync_output += "_$Destination_Server.txt"
    Invoke-ASCmd –InputFile $XML_file -Server $Destination_Server[$Destination_Server.length -1] >$sync_output
}

он делает то, что ему нужно, за исключением sync_output, я получаю это созданное:

enter image description here

, как вы можете видеть, первый файл,

CUBE_Destination_Server1

isотлично создано.

однако второй файл должен называться

CUBE_Destination_Server2

, но вместо этого он по какой-то причине добавляет Destination_Server2 после добавления Destination_Server1 дважды ...

Почему это?

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Строка добавляется, потому что это то, что вы сказали ей сделать.

Прямо вверх, += говорит добавить новое содержимое в конце, так что в случае

$sync_output = Join-Path $syncPATH $CUBE_input
...
$sync_output += "_$Destination_Server.txt"

Он устанавливает строку, а затем добавляет элементы в конец этой строки и продолжает добавлять к ней каждый раз, когда эта команда выполняется, когда цикл ForEach-Object циклически повторяется.Это усугубляется вашим другим использованием +=, который добавляет объекты в массив, так как вы устанавливаете $Destination_Server = @(), который устанавливает эту переменную как пустой массив.Поэтому, когда вы добавляете к своей строке, вы добавляете весь массив к этой строке.

Итак, чтобы повторить ваш пример:

$sync_output = 'CUBE'
$destination_server = @()

Затем внутри цикла на первом проходе вы добавляете строкук массиву:

$destination_server += 'Destination_Server1'

Так что в этом массиве есть 1 элемент.Затем вы добавляете этот массив к $sync_output, который при расширении переменных в основном выглядит следующим образом:

"CUBE" += "_Destination_Server1.txt"

Так что теперь $sync_output имеет значение CUBE_Destination_Server1.txt.Следующая итерация цикла!Вы добавляете еще одну строку в массив $Destination_Server:

$destination_server += 'Destination_Server2'

Теперь, когда в массиве есть 2 строки, поэтому, когда вы добавляете его в строковую переменную $sync_output, вы, по сути, делаете это:

"CUBE_Destination_Server1.txt" += "_Destination_Server1Destination_Server2.txt"

Это происходит потому, что массив строк просто объединяет все строки в своем массиве в одну строку.Чтобы действительно это исправить, вы должны быть последовательными и ссылаться на последнюю строку в массиве.Я рекомендую не использовать одну и ту же переменную для этого и буду использовать $sync_output_file.

$sync_output = Join-Path $syncPATH $CUBE_input
$i=0
$Destination_Server = @()

foreach($row in $Table | where { $_.cube_name -match $CUBE })
{   
    $i++
    $Destination_Server += $row.Item("query_server")
    write-host " > Query Server $($i):" $Destination_Server[$Destination_Server.length -1]
    $sync_output_file = $sync_output + '_' + $Destination_Server[-1] + '.txt'
    Invoke-ASCmd –InputFile $XML_file -Server $Destination_Server[$Destination_Server.length -1] >$sync_output_file
}

Редактировать: Вот почему $Destination_Server[$Destination_Server.length - 1] работает как $Destination_Server[-1]:

В PowerShell каждый элемент в массиве имеет индекс.Этот индекс основан на нуле.Вы можете ссылаться на элемент в массиве по его порядковому номеру, например $Array[X], где X - это порядковый номер интересующего вас элемента. Поэтому, учитывая этот массив:

$MyArray = 'cat','dog','fish','goat','banana'

Если вы ссылаетесь$MyArray[0] вернет cat, так как это первый элемент в массиве.С массивами в PowerShell свойства .length и .count являются синонимами, поэтому, когда вы ссылаетесь на $MyArray.length, вы просто получаете количество элементов в массиве.Когда вы подсчитываете элементы, вы начинаете с 1, но индексы массива начинаются с 0, поэтому вам нужно сделать .length - 1, чтобы получить номер индекса последнего элемента в массиве.В моем примере, если мы сделаем $MyArray.Length, он вернет 5, потому что в моем массиве есть 5 элементов.Таким образом, $MyArray[$MyArray.Length - 1] - это, по сути, $MyArray[5 - 1] или $MyArray[4], который является последним элементом в $MyArray.

В дополнение к ссылкам на элементы по индексу вы также можете использовать отрицательные числа, которые начинаются сконец массива и считать в обратном направлении.Этот метод не основан на нуле, поэтому $MyArray[-1] ссылается на последний элемент в массиве, точно так же, как $MyArray[-2] является вторым по отношению к последнему элементу в массиве.

Таким образом, разница между $MyArray[$MyArray.length - 1] и $MyArray[-1] заключается в том, что в первом вы вычисляете номер индекса для последнего элемента в массиве, где второй ссылается на последний элемент в массиве независимо от того, какой у него номер индекса.

Вы также можете указать диапазоны этогоКстати, $MyArray[0..2] даст вам первые 3 элемента в массиве, а $MyArray[-2..-1] даст вам последние 2 элемента в массиве.Это на самом деле не относится к вашей ситуации прямо сейчас, но это полезно знать в целом и может быть полезно в будущем для вас.

0 голосов
/ 18 сентября 2018

Оператор += добавляет .Итак, эта строка:

$sync_output += "_$Destination_Server.txt"

принимает существующее значение $sync_output и затем добавляет "_$Destination_Server.txt" в конец.

Один из способов получить желаемый результат - присвоить (не добавлять)) $syncResult внутри вашего цикла, с таким утверждением:

$sync_output = (Join-Path $syncPATH $CUBE_input) + "_$Destination_Server.txt"

Обновление: похоже, у вас похожая проблема с переменной $Destination_Server - вы должны использоватьпростое присвоение (=) вместе с ним, а не добавление (также называемое конкатенацией) (+=).

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