命令行查找和替换后特殊字符变成问号

Owe*_*vin 4 powershell automation cmd

我有一个文本文件input.xlf

\n
  <trans-unit id="loco:5e7257a0c38e0f5b456bae94">\n    &lt;source&gt;Login</source>\n    <target>\xe7\x99\xbb\xe5\x85\xa5</target>\n    <note>Login Header</note>\n  </trans-unit>\n
Run Code Online (Sandbox Code Playgroud)\n

基本上我需要&lt;<和替换&gt;\'>\',所以我运行下面的脚本

\n

跑步者.bat

\n
powershell -Command "(gc input.xlf) -replace \'&lt;\', \'<\' | Out-File -encoding ASCII output.xlf";\npowershell -Command "(gc output.xlf) -replace \'&gt;\', \'>\' | Out-File -encoding ASCII  output.xlf";\n
Run Code Online (Sandbox Code Playgroud)\n

上面的内容一直有效,直到我注意到下面的输出

\n
  <trans-unit id="loco:5e7257a0c38e0f5b456bae94">\n    <source>Login</source>\n    <target>??????</target>\n    <note>Login Header</note>\n  </trans-unit>\n\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试删除编码,但现在我得到了

\n
 <trans-unit id="loco:5e7257a0c38e0f5b456bae94">\n   <source>Login</source>\n   <target>\xc3\xa7\xe2\x84\xa2\xc2\xbb\xc3\xa5\xe2\x80\xa6\xc2\xa5</target>\n   <note>Login Header</note>  \n </trans-unit>\n\n
Run Code Online (Sandbox Code Playgroud)\n

以下是我想要的输出

\n
  <trans-unit id="loco:5e7257a0c38e0f5b456bae94">\n    <source>Login</source>\n    <target>\xe7\x99\xbb\xe5\x85\xa5</target>\n    <note>Login Header</note>\n  </trans-unit>\n
Run Code Online (Sandbox Code Playgroud)\n

mkl*_*nt0 7

(可能)存在两个字符编码问题

  • 输出时,使用-Encoding Ascii保证“有损地”将任何非 ASCII 范围字符转写为文字字符?

    • 要保留所有字符,必须选择Unicode编码,例如 -Encoding Utf8
  • input上,您必须确保 PowerShell 正确读取输入文件。

    • 具体来说,Windows PowerShell将无 BOM 的UTF-8 文件错误解释为ANSI编码,因此您也需要使用-Encoding Utf8with Get-Content

此外,您可以通过一次 调用来摆脱困境powershell.exe,并且您还可以优化此调用:

powershell -Command "(gc -Raw -Encoding utf8 input.xlf) -replace '&lt;', '<' -replace '&gt;', '>' | Set-Content -NoNewLine -Encoding Utf8 output.xlf"
Run Code Online (Sandbox Code Playgroud)
  • 使用-Rawwith gc( Get-Content) 将文件作为一个整体读取,而不是读取到行数组中,这可以加快-replace操作速度。

  • 可以连锁 -replace经营

  • 对于已经是文本(字符串)的输入,Set-Content通常是更快的选择。[1]
    -NoNewLine防止附加额外的尾随换行符。


[1] 这里实际上没有什么区别,因为只写入了一个字符串,但对于许多输入字符串(逐行输出),它可能会 - 请参阅此答案