Powershell — диапазон массива от пользовательского ввода

#powershell #powershell-2.0

#powershell #powershell-2.0

Вопрос:

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

Например:

 function MyArrayOfMachines {
[CmdletBinding()]
param(
    [parameter(Mandatory=$true)][string]$Machine
    # What should I assign the $Range variable as?
    )
 # Hardcoded range. User should be able to enter the range
 $Range = 2..5
 for ($i=0; $i -lt $array.length; $i  =1)
 {
   $result = $array[$i]
   $output = $machine $result
   $output
 }
}
  

Приведенная выше функция должна принимать входные данные в виде имени компьютера и диапазона массива. На данный момент у меня жестко задан диапазон массивов. Когда я назначаю $Range как [Array] $Range в приглашении пользователя, появляется запрос на $Range [0] и т.д. и т.п. Но я бы хотел, чтобы пользователь ввел диапазон.

Ответ №1:

Разве это не работает? Если я не неправильно понял ваш вопрос…

 function test($range){

$range

}

test -range (1..5)
  

Комментарии:

1. Спасибо! Это работает. Но мой вариант использования — принимать ввод от пользователя во время запроса для $range, если пользователь вводит (1 ..5) , разве это не будет рассматриваться как набор строк и приводить к machine(, machine1, machine.,machine.,machine5 в качестве результата?

2. @Sanjeev Нет, этого не произойдет. (1..5) будет рассматриваться как массив целых чисел. Попробуйте запустить пример в моем ответе.

Ответ №2:

Вы также можете принять диапазон в виде строки и проанализировать его самостоятельно:

    function Test
    {
    param($range)

    if($range -is [String])
        {
        [int]$start, [int]$end = $range.split('.', [StringSplitOptions]::RemoveEmptyEntries)
        $start..$end
        }
    else
        {
        $range
        }
    }
  

Причина if / else заключается в случаях, когда пользователь передает фактический диапазон, как в ответе manojlds, а не строку для анализа (например, 1 ..5). Это означает, что вы не можете строго ввести параметр.

Ответ №3:

Сделайте это двумя параметрами:

 function test{
    param ( [int]$st,
            [int]$end)

    $Range = $st..$end
    $Range
}

test 1 5
  

Если они вводят начало и конец диапазона, вы можете использовать это для его динамического создания в функции.

Редактировать:

Чтобы получить диапазон из строки, попробуйте:

 function test{
    param ($Range)

    $NewRange = $Range.substring(0,($Range.indexof('.')))..$Range.substring(($Range.lastindexof('.')   1))
    $NewRange
}

test 1..5
  

Комментарии:

1. Да. Это работает! Все еще пытаюсь выяснить, возможно ли получить диапазон в одном приглашении вместо использования двух приглашений ввода 🙂

2. Рассматривая другие варианты, я бы просто использовал две целочисленные переменные $ st и $ end. Думаю, по крайней мере, таким образом, пользователю не нужно знать о формате для ввода диапазона массива.

Ответ №4:

Я согласен с @manojlds, диапазон должен быть передан в виде массива. Синтаксический анализ строки ограничивает возможности ввода пользователем. С помощью [int[]] вы можете заставить пользователя указать массив целых чисел. Это также позволило бы пользователю указывать разбитый диапазон, например, ((2..4) (6..12)) который сложнее разрешить при разборе строк.

В вашем примере я не уверен, откуда $array берется, и вам нужна только одна строка, чтобы вернуть имя вычисляемой машины.

 function MyArrayOfMachines {
    param(
    [parameter(mandatory=$true)]
    [string] $machine,

    [parameter(mandatory=$true)]
    [int[]] $range
    )

    foreach($n in $range) {
        $machine $n
    }
}
  

Вы могли бы создать одно имя компьютера,

 MyArrayOfMachines Laptop 1
  

диапазон машин,

 MyArrayOfMachines Workstation (2..10)
  

или непоследовательный массив машин

 MyArrayOfMachines Server ((2..3) (5..9))
  

Комментарии:

1. Извините, если я не понял. Я хочу, чтобы пользователь ввел диапазон. Например, я запускаю функцию в окне powershell и ввожу имя функции.C:> MyArrayOfMachines, теперь пользователю предлагается ввести запрос для машины и диапазона [0]. Диапазон [0] не принимает (2..10) в качестве допустимого значения. Если функция вызывается с аргументами, она работает нормально. Но я хочу, чтобы пользователь вводил значения для параметров во время выполнения.

Ответ №5:

Вы могли бы просто передать строку и оценить ее:

 function Test([string]$range) {
  if ($Range -match '^d ..d $') {
    $RangeArray = Invoke-Expression $Range
  } else {
    $RangeArray = 1..5
  }
}
  

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