如何使用.bat格式化将unicode文件批量格式化为ANSI文件?

时间:2017-03-13 22:57:04

标签: batch-file unicode

.bat编程的初学者总数,所以请耐心等待: 我一直在尝试将从科学仪器收集的大量Unicode文件数据库转换为ANSI格式。此外,我需要将所有这些文件转换为.txt文件。

现在,第二部分非常简单 - 我过去常常使用“批量重命名实用程序”,我认为到目前为止我已经能够使它工作了。

第一部分应该非常简单,我发现了多个不同的类似问题,但它们似乎都适用于powershella single file,或者在有关特定编码的长篇讨论中结束正在使用。 One question seems to match mine exactly,但是在尝试了他们建议的代码之后,只有一半的文件似乎转移得很好,另一半来自无意义的代码。我一直在使用代码:

Cat c = (Cat)new Animal();
c.play();

然后删除/移动额外的文件。

我在过去(左)成功手动转换了文件,但当前的编码似乎失败了(右): Side by side comparison of files encoded by hand vs by program

我的问题是:

  1. 我可以从我的乐器中获取单个文件 多个编码(部分UTF-8,部分UTF-16),这是 弄乱我的程序(或者更可能的是,我正在使用的编码是 太小)?如果是这样的话,我明白为什么特别 像平方和度数符号这样的字符正在破碎,但是 不是数据,只是数字。
  2. 我的代码中是否有一些明显的拼写错误导致了这种奇怪的现象 错误?
  3. 如果错误可能嵌入了unicode(8 vs 16 vs 32)或 ANSI(1252 vs ???)我正在使用,我该怎么检查?
  4. 如何修复此代码?
  5. 如果我有任何问题需要提出或我需要补充的其他信息,请告知我们。谢谢!!

1 个答案:

答案 0 :(得分:1)

  

我从我的乐器获得的单个文件是否可能采用多种编码(部分UTF-8,部分UTF-16),并且这会弄乱我的程序(或者更可能的是,我正在使用编码太小了)?

我不相信单个文件可以包含多个编码。

  

我的代码中是否有一些明显错误导致了这个奇怪的错误?

cmd环境可以很容易地处理不同的代码页,但它很难处理多字节编码和字节顺序标记。实际上,当尝试读取UCS-2 LE中返回的WMI结果时,这是一个常见问题。尽管存在用于清理WMI结果的a pure batch workaround,但遗憾的是,它并不普遍适用于所有其他编码。

  

如果错误可能嵌入了unicode(8 vs 16 vs 32)或ANSI(1252 vs ???)我使用,我该怎么检查?我如何修复此代码?

.NET更善于处理未知编码的文件。 StreamReader class在读取其第一个字符时,将读取BOM并自动检测文件编码。我知道您希望避免使用PowerShell解决方案,但PowerShell确实是访问IO方法以透明地处理这些文件的最简单方法。

有一种简单的方法可以将PowerShell混合代码合并到批处理脚本中。使用 .bat 扩展程序保存它,看看它是否符合您的要求。

<# : batch portion
@echo off & setlocal

powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF
: end batch / begin PowerShell hybrid #>

function file2ascii ($infile, $outfile) {

    # construct IO streams for reading and writing
    $reader = new-object IO.StreamReader($infile)
    $writer = new-object IO.StreamWriter($outfile, [Text.Encoding]::ASCII)

    # copy infile to ASCII encoded outfile
    while (!$reader.EndOfStream) { $writer.WriteLine($reader.ReadLine()) }

    # output summary
    $encoding = $reader.CurrentEncoding.WebName
    "{0} ({1}) -> {2} (ascii)" -f (gi $infile).Name, $encoding, (gi $outfile).Name

    # Garbage collection
    foreach ($stream in ($reader, $writer)) { $stream.Dispose() }
}

# loop through all .001 files and apply file2ascii()
gci *.001 | %{
    $outfile = "{0}\{1}.txt" -f $_.Directory, $_.BaseName
    file2ascii $_.FullName $outfile
}

虽然使用get-contentout-file cmdlet可以简化此过程可以简化,但上面演示的IO流方法将避免您必须将整个数据文件加载到内存中 - 如果您的任何数据文件很大,则会带来好处。