Home > database >  How to preserve multiple spaces as a string argument for powershell in cmd in Windows 10
How to preserve multiple spaces as a string argument for powershell in cmd in Windows 10

Time:08-11

I am trying to run a powershell command with several string arguments via cmd.

The context is that I want to use the Compress-Archive cmdlet from a Matlab function/script. And Matlab only has access to cmd.

But I can't find a way to preserve consecutive spaces in the string arguments when calling powershell.exe in cmd.

C:\Users\Artus>powershell.exe echo 'a   c'
a c

C:\Users\Artus>powershell.exe echo \"a   c\"
a c

C:\Users\Artus>powershell.exe echo `"a   c`"

c`

C:\Users\Artus>powershell.exe echo \"`'a   c`'\"
'a c'

I tried to adapt the answers for this, this and this questions and none worked.

How does one avoid the removal of consecutive spaces when passing arguments to powershell.exe? Is there a way to ask powershell.exe to accept an argument as string literal?

CodePudding user response:

To add an explanation to Theo's effective solution:

# Use of "..." around the entire argument is the key.
# (The extra space before and after the command is just for visual clarity.)
powershell.exe " echo 'a    c' "

# Alternative with embedded double-quoting
powershell.exe " echo \"a    c\" "

That is, enclosing the entire command in "..." is necessary to avoid the whitespace normalization you saw.


When you pass a command (piece of PowerShell code) to the PowerShell CLI, via the -Command (-c) parameter (which is positionally implied in your case), PowerShell performs the following command-line parsing first, by splitting the command line into:

  • white-space separated tokens
  • with double-quoted tokens ("...") getting recognized as single tokens even if they contain spaces, with the interior spaces getting preserved as-is; note that these (unescaped) " are removed in the process).
    • Note: By contrast, '...'-enclosed tokens are not recognized as single tokens on the command line (even though inside a PowerShell session they are), so that 'a b' is split into verbatim 'a and b'.

The resulting tokens are then joined with a single space to form the single string that is then interpreted and executed as PowerShell code.

It is during the splitting by whitespace - which can be any number of spaces between tokens - that the information about how many spaces there were between tokens is lost.

Only inside "..."-enclosed tokens is the whitespace preserved as-is, hence the use of "..." around the entire command above.

If you need to use " quoting as part of the PowerShell command (to use string interpolation), " characters must be escaped as \", as shown in the second command at the top. However, if you're calling from cmd.exe / a batch file, this may break due to how cmd.exe parses command lines. In such edge cases, use the workarounds discussed in this answer.

  • Related