Почему Powershell заменяет запятые пробелами?

#string #powershell #split

#строка #powershell #разделение

Вопрос:

Я делаю некоторый скрипт в Powershell для автоматизации задачи. Этот скрипт получит аргументы, такие как:

 PS > myscript.ps1 par=a,1,2,0.1 par=b,3,4,0.1 par=c,5,6,0.1 bin=file.exe exeargs="fixed args for file.exe"
  

Короче говоря, file.exe это исполняемый файл, который принимает параметры (включая a, b и c), и этот сценарий ps1 будет выполнять file.exe передачу аргументов a b c в пределах указанного диапазона, изменяя их с указанной точностью.

Вопрос в том, что сначала я разделяю каждый $arg in $args символ на символ «=», а затем я должен разделить их на «,», чтобы получить указанные значения.

Дело в том, что когда я делаю:

 foreach ($arg in $args)
{
    $parts = ([string] $arg).split("=")
    Write-Host $parts[1]
}
  

Вывод

 a 1 2 0.1
b 3 4 0.1
c 5 6 0.1
file.exe
fixed args for file.exe
  

Т.е. Он уже заменил символ «,» пробелом, поэтому мое второе разделение должно быть с пробелом, а не с запятой.

Есть какие-нибудь предположения о том, почему это происходит?

Заранее спасибо!

Ответ №1:

Прежде всего, почему вы пишете это как программу на C или что-то в этом роде? Вам не нужно передавать подобные аргументы, использовать $args и разделять = и т. Д. когда Powershell имеет более мощную концепцию параметров, с помощью которой вы можете передавать именованные параметры и аргументы, а не выполнять синтаксический анализ, который вы выполняете. ( Подробнее о параметрах здесь: http://technet.microsoft.com/en-us/library/dd315296.aspx )

С учетом сказанного позвольте мне ответить на ваш вопрос:

То, что вы делаете, когда вы передаете аргументы, такие как:

par=a,1,2,0.1 par=b,3,4,0.1 par=c,5,6,0.1 bin=file.exe exeargs="fixed args for file.exe"

вы передаете массив массивов. Первый элемент — это массив с элементами:

 par=a
1
2
0.1
  

Хорошо, переходим к разделению:

Когда вы это делаете [string] $a , вы преобразуете массив в строку. По умолчанию это означает, что массив с элементами 1,2,3 станет 1 2 3 .

Итак, ваш первый аргумент там par=a,1,2,0.1 становится par=a 1 2 0.1 , и разделение на = средства parts[1] становится a 1 2 0.1 , что вы и видите.

Итак, как вы можете сохранить запятую?

Просто создайте массив, который будет преобразован в строку с , промежуточным значением, а не пробелом, верно?

Вот несколько способов сделать это:

Использование -join operator:

 foreach ($arg in $args)
{

    $parts = ($arg -join ",").split("=")
    Write-Host $parts[1]
}
  

теперь вы увидите вывод с нужными запятыми.

Другой способ, используя $ofs специальную переменную:

 foreach ($arg in $args)
{
    $ofs =","
    $parts = ([string] $arg).split("=")
    Write-Host $parts[1]
}
  

(подробнее о $ ofs здесь: http://blogs.msdn.com/b/powershell/archive/2006/07/15/what-is-ofs.aspx )

Отказ от ответственности — Все это объяснение, чтобы вы поняли, что происходит. Пожалуйста, не продолжайте это и используйте параметры.

Ответ №2:

Это происходит при синтаксическом анализе командной строки для вашего скрипта, а не во время метода split() . Чтобы увидеть это, попробуйте поместить «Write-Host $args» в начале, например:

 Write-Host $args
foreach ($arg in $args)
{
    $parts = ([string] $arg).split("=")
    Write-Host $parts[1]
}
  

Это потому, что символ ‘,’ используется для разделения элементов в массиве. Например:

 PS C:temp> $a = 1,2,3
PS C:temp> Write-Host $a
1 2 3
PS C:temp> $a.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
  

Попробуйте вместо этого использовать эту командную строку:

 .myscript.ps1 "par=a,1,2,0.1" "par=b,3,4,0.1" "par=c,5,6,0.1" "bin=file.exe" "exeargs=fixed args for file.exe"
  

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

1. Да, я пробовал что-то подобное: ставить лайк par="a,1,2,0.1" и так далее. Но это скучно, ставить «вокруг каждого параметра. Знаете ли вы какую-либо причину, по которой powershell это делает? ty

2. Отредактировано — В основном символ ‘,’ позволяет анализировать его как массив, а не просто строку