问题
How do you properly escape quotes in powershell v2 (called from within a batch file)?
I have tried:
powershell -Command "(gc file1.txt) -join "`n" | Out-File file2.txt"
and
powershell -Command "(gc file1.txt) -join ""`n"" | Out-File file2.txt"
and
powershell -Command "(gc file1.txt) -join '"`n`" | Out-File file2.txt"
but they all fail.
Editor's note: The purpose of the command is to transform Windows CRLF line breaks to Unix LF-only ones, so as to create a file that will be processed on Linux.
回答1:
From a batch file (cmd.exe), you must \-escape embedded " instances
(even though PowerShell-internally it is ` (the backtick) that serves as the escape character):
As wOxxOm points out in a comment on the question, using """ to embed a single " is also an option.
However, given that most command-line utilities support \", \" is easier to remember.
powershell -Command "(gc file1.txt) -join \"`n\" | Set-Content -NoNewLine file2.txt"
Note:
Set-Content -NoNewlinerequires PSv5+.Set-Contentwrites "ANSI"-encoded files by default (e.g., based on code page Windows-1252 on US-English systems); use the-Encodingparameter to change that.- Since you're only dealing with strings,
Set-Contentis preferable toOut-File, which is only needed if you have non-string objects that must have PowerShell's default formatting applied to them first.
- Since you're only dealing with strings,
Consider using
powershell -NoProfile ...to suppress loading of PowerShell's profile files, both for faster execution and for a more predictable execution environement.
PSv2 solution:
Unfortunately, prior to PSv5, only the Write-Host cmdlet supports the -NoNewline parameter (introduced in v2), which is of no help here, so the .NET framework must be used:
powershell -Command "[IO.File]::WriteAllText(\"$PWD/file2.txt\", ((gc $PWD/file1.txt) -join \"`n\") + \"`n\")"
Note the need to use path prefix $PWD explicitly, because the .NET Framework's current directory typically differs from PowerShell's.
Also, the output file's encoding will be UTF-8, without a BOM, but you can pass a different encoding as the 3rd argument to [IO.File]::WriteAllText(), such as [System.Text.Encoding]::Default to match Set-Content's default behavior (as of Windows PowerShell v5.1).
Optional reading: platform-specific line breaks "`n" vs. "`r`n" vs. [Environment]::Newline
Implicit choice of newlines (line breaks):
when reading, PowerShell accepts LF-only (Unix-style) and CRLF (Windows-style) newlines (line breaks) interchangeably.
when writing (e.g., when sending an array of lines / objects to a file with
>/Out-File/Set-Content), PowerShell uses the platform-appropriate newline sequence.
Note, however, that any newline sequences embedded in a given string input object are sent to the file as-is.
As for escape sequences / constants:
[Environment]::Newlinecontains the platform-appropriate newline."`n"is always just LF (\n)as evidenced by
"`n".Lengthreturning1and[char] 10 -eq [char] "`n"returning$True(10is the decimal Unicode/ASCII code point of LF).The documentation isn't explicit about this: Get-Help about_Special_Characters mentions "new line" and "line break", without mentioning what specific character [sequence] that represents. (As mentioned, LF by itself is just as valid a line break as CRLF is in PowerShell).
Therefore, to create CRLF sequences, you must use
"`r`n".
As for multi-line string literals in scripts (including here-documents):
- They reflect their source file's newline style. That is, if your script uses CRLF newlines, so will the newlines embedded in the multi-line string.
回答2:
Here's one way to do it from the PowerShell command line:
(Get-Content Input.txt -Raw) -replace "`r`n","`n" | Out-File Output.txt -Encoding ASCII -NoNewline
As others have noted this is a PowerShell v5 solution (-Raw appeared in v3, and -NoNewline appeared in v5).
Here's a PowerShell v2 version of the same thing:
$content = [IO.File]::ReadAllText("C:\Path\Input.txt") -replace "`r`n","`n"
[IO.File]::WriteAllText("C:\Path\Output.txt", $content)
(The paths are needed because the .NET methods don't use PowerShell's "current location".)
来源:https://stackoverflow.com/questions/44637110/how-to-properly-escape-quotes-in-powershell-v2