Girardi
Girardi

Reputation: 2811

Why does Powershell replace commas with whitespaces?

I'm doing some script in Powershell to automate a task. This script is going to get arguments, such as:

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"

In short, file.exe is an executable which accept parameters (including a, b and c) and this ps1 script is going to execute file.exe passing args a, b and c within the specified range, varying 'em by the specified precision.

The question is, I first split each $arg in $args by the character "=", and then I should split them by "," to get the specified values.

The thing is, when I do:

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

The output is

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

I.e., it already substituted the "," character with a whitespace, so my second split should be with white space, not with comma.

Any guess on why does it happen?

Thanks in advance!

Upvotes: 2

Views: 4591

Answers (2)

manojlds
manojlds

Reputation: 301147

First of all why are you writing it like a C program or something? You don't have to pass arguments like that, use $args and split on = etc. when Powershell has a more powerful concept of parameters, whereby you can pass the named paramters and arguments rather than doing the parsing that you are doing. ( More on parameters here: http://technet.microsoft.com/en-us/library/dd315296.aspx)

With that said, let me answer your question:

What you are doing is when you pass in arguments like:

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"

you are passing in array of arrays. The first element is the array with elements:

par=a
1
2
0.1

Ok coming to the split:

When you do [string] $a, you are converting the array into a string. By default this means an array with elements 1,2,3 will become 1 2 3.

So your first argument there par=a,1,2,0.1, becomes par=a 1 2 0.1 and the split on = means parts[1] becomes a 1 2 0.1, which is what you see.

So how can you retain the comma?

Just make an array to be converted into a string with , inbetween than space, right?

Here are some ways to do that:

Using -join operator:

foreach ($arg in $args)
{

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

now you will see the output with the commas that you want.

Another way, using $ofs special variable:

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

(more on $ofs here: http://blogs.msdn.com/b/powershell/archive/2006/07/15/what-is-ofs.aspx )

Disclaimer - All this explanation to make you understand what is happening. Please do not continue this and use paramters.

Upvotes: 4

Scigrapher
Scigrapher

Reputation: 2116

This is happening in the parsing of the command line for your script and not during the split() method. To see this, try putting a "Write-Host $args" at the beginning, like so:

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

This is because the ',' character is used to separate elements in an array. For example:

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

Try this command line instead:

.\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"

Upvotes: 2

Related Questions