1

I wanted to do the same as Powershell call cmd.exe command like copy /b but now I have problem with quote : ' was unexpected at this time.

I tried to escape with \ but it's worse

function concat-filenames {
   cmd.exe --% /c (echo file '$($args[0])' & echo file '$($args[0])' )>list.txt
}
user310291
  • 36,946
  • 82
  • 271
  • 487

2 Answers2

3

--%, the stop-parsing symbol, cannot be combined with PowerShell variables and expressions, because it passes the remainder of the command line through to the target executable - cmd.exe in this case - as-is, the only exception being the expansion (interpolation) of cmd.exe style environment-variable references, such as %USERNAME%.

Generally, --% comes with many limitations - see this answer.

Something like the following should work; note that & must be quoted in order to be passed through to cmd.exe, whereas >, due to being unquoted, is interpeted by PowerShell.

function concat-filenames {
  cmd.exe /c echo file $args[0] '&' echo file $args[0] > list.txt
}

Note that in cmd.exe trailing spaces after an echo command, before a subsequent operator (such as & or >), become part of the output.

If you meant to pass the single quotes as part of the value (as opposed to their syntactic use as a PowerShell string literal), use expandable strings ("..."):

function concat-filenames {
  cmd.exe /c echo file "'$($args[0])'" '&' echo file "'$($args[0])'" > list.txt
}

Note that in both cases PowerShell performs re-quoting on demand behind the scenes: if the expanded (interpolated) argument value contains spaces, it is wrapped in double quotes ("...").

mklement0
  • 382,024
  • 64
  • 607
  • 775
1

Please try to load/use the raw-content.

By default, Get-Content parses (or tries to) the input as an array of type X (commonly as an array of String).

After a short test .. as Byte (with PS 5.1 using "-Encoding Byte" and with PS 6+ using "-AsByteStream") the PowerShell engine streams that "parsed" input to the pipeline not as a whole. (The PS6+ parameter name indicates that already).

Therefore try to use the "-Raw" parameter for that. Since you don't want to loop trough the input in any way you don't need an enumerable object. You need it raw for performance.

Test the following:

PS 5.1

Get-Content $args[0], $args[1] -Encoding Byte -Raw | Set-Content -Path 'output.txt' -Encoding Byte

PS 6+

Get-Content $args[0], $args[1] -AsByteStream -Raw | Set-Content -Path 'output.txt' -AsByteStream

PS: The memory usage will be higher than the default streaming method. If your binary files are not that big, this shouldn't be an issue.

swbbl
  • 814
  • 1
  • 4
  • 10
  • Note that you're not answering the question at hand, but a different question that the question body merely _links to_. – mklement0 Nov 14 '20 at 20:12