(问题重写以变得更加有用)
我有一个批处理脚本,它将与命令行程序交互,获取其输出,然后根据该输出执行决策。
我需要与之交互的程序之一相当老旧,所以我只能忍受它的怪癖。当我将其输出通过管道传输到文本文件时,该文本文件采用 UTF-16 LE 编码。
以下是我的方法:
program -parameter > resultat.txt
在Windows 7下,这种编码似乎给cmd/batch工作带来了麻烦,因为无法将这样的文本文件的内容读入变量。
这是一个例子,(这只使用文本文件的第一行):
set /p Var=<resultat.txt
echo %Var%
cmd /k
它只是没有任何回应,只是说“ECHO 已打开”。
此外,如果您使用“类型”来打印文本文件的内容,则会出现奇怪的间距,这表明它没有被正确处理。
尝试的解决方案[1] - Powershell
经过研究,发现powershell可以转换txt编码,使用方法如下:
Get-Content -Path "path\file.txt" | Out-File -FilePath "path\new_file.txt" -Encoding <encoding>
使用 Notepad++,我做了一些研究,我需要获得什么编码?
UTF-8(无 BOM),相当于记事本中的“ANSI”,是我需要的编码,当使用此编码时,将文本文件加载到变量和“type”命令都可以正常工作。我怎么知道的?如果我在记事本中打开管道文本文件,然后重新保存为“ANSI”编码,一切都会正常工作。
-Encoding ascii
...这个选项应该有效,因为它会产生 UTF-8(无 BOM)的结果,但它似乎无法处理 UTF-16 LE 源编码格式,并且不会产生可用的输出。当我在 Notepad++ 中打开结果文件时,它将其标识为 UTF-16 LE“Unix”,这很奇怪。
有趣的是:如果我在记事本中将管道 txt 文件重新保存为“unicode”,则会生成一个 UTF-16 LE BOM 文件,该文件与上述转换参数配合使用可生成完美的 UTF-8 文件。此时,我扩展了我的研究范围,并提出了一个问题“如何将 BOM 添加到 UTF-16 LE 编码?”因为我可以将这些知识与 powershell 知识结合起来。但是,剧透警告:我未能找到一个合适的答案。
-Encoding utf8
...是另一个类似的选项,但它会生成一个 UTF-8 BOM 文件(相当于在记事本中保存为“UTF-8”),这会产生损坏的输出。
总结一下:
我正在寻找一个命令行工具/方法(开放或专有,第一方或第三方),以便能够实现如下转换:
UTF-16 LE - Windows(CR LF) 直接转换为 UTF-8 - Windows(CR LF)
UTF-16 LE - Windows(CR LF) 至 UTF-16 LE BOM - Windows(CR LF)
答案1
如果UTF16type
文件不包含物料清单:
type utf16.txt >ascii.txt
但是,正如您的情况一样,生成的文件确实有一个 BOM,转换文件的一个可靠方法是使用 PowerShell:
powershell "Get-Content 'utf16.txt' | Out-File 'ascii.txt' -Encoding ascii"
注意使用两种类型的引号,以避免需要转义内部引号。
答案2
find /v "" sourcefile > destinationFile
这将读取源文件的内容,并打印任何与“”(无)不匹配的行 - 从而打印整个文件的内容。
对于我来说,find 命令似乎可以很好地解析 UTF-16,并且恰好输出纯 ascii,因此,您的目标文件将包含与源相同的文本,但是将是 ascii。
答案3
阻力最小的路径:在 Windows 上使用 libiconv
经过大约一天的搜索(回到提出问题的时候),我注意到 Stackoverflow 有一个名为 [utf16-le] 的标签,我决定值得花时间浏览使用此标签的所有线程。
我找到了一个解决方案,它展示了一个名为“iconv”的程序,甚至还展示了执行转换所需的完整命令。与 powershell 方法不同,您需要准确指定输入编码以及输出编码,但与 powershell 方法不同的是,它会产生良好的结果。
以下是有用的帖子:
https://stackoverflow.com/questions/17287713/using-iconv-to-convert-from-utf-16le-to-utf-8
iconv 不是 Windows 实用程序,但它显然被移植到 Windows,虽然上面链接的问题是使用 [Linux] 标签询问的,但其中一个答案包含一个与 Windows 完全兼容的示例:
iconv -f UTF-16LE -t UTF-8 infile > outfile
我从这里下载了文件:
https://sourceforge.net/projects/gnuwin32/files/libiconv/1.9.2-1/
我只需要“bin”(二进制)和“dep”(依赖项),将两者的内容提取到同一个文件夹中,就可以了。
答案4
对于“添加缺失的BOM”选项:我没有7,但有8.1(或10):
打开记事本,不要输入任何内容,然后保存为 Unicode(10 中的 UTF16LE);这将创建一个包含仅有的小端字节序 BOM
copy bomfile+bomless_utf16le newfile
结果对于我type
和 powershell都有效get-content
。
但它不像查尔斯那样狡猾find /v ""
!