2017-03-13 384 views
3

總的初學者到.bat編程,請耐心等待: 我一直在試圖將從科學儀器收集的Unicode文件的海量數據庫轉換爲ANSI格式。此外,我需要將所有這些文件轉換爲.txt文件。如何使用.bat格式將unicode文件批量格式化爲ANSI文件?

現在,第二部分是非常微不足道的 - 我曾經用「批量重命名實用程序」來做到這一點,並且我已經能夠使其工作到目前爲止,我認爲。

第一部分應該是非常簡單的,我發現了多個不同的類似問題,但它們似乎都適用於powershell,a single file,或者結束了關於所使用的特定編碼的長篇討論。 One question seems to match mine exactly,但嘗試過他們的建議代碼,只有一半的文件似乎傳輸正常,另一半來作爲無稽之談的代碼。我一直在使用代碼:

for %%F in (*.001) do ren "*SS.001" "*SS1.001" 

for %%F in (*.001) do type "%%F" >"%%~nF.txt" 

然後刪除/移動額外的文件。

我已經轉換用手文件成功,在過去(左),但目前的編碼似乎(右)失敗: 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. 我該如何解決這段代碼的工作?

如果有任何更好的問題,我應該詢問或需要補充的其他信息,請讓我知道。謝謝!!

+1

ANSI編碼不支持編碼所有Unicode字符。大多數支持每個只能代表256個Unicode字符。所以如果你有俄文字符但編碼到ANSI代碼頁1252(西歐),你將失去信息。 –

+0

存儲在文件中的值是否可能是二進制而不是Unicode?如果有的話,沒有標準的工具可以幫助你。 –

+1

你怎麼知道他們是「Unicode」文件?那不是真的。文件需要編碼。微軟記事本所稱的「Unicode」實際上是小端的UTF-16編碼。您的屏幕截圖看起來像記事本,因此只需選擇「文件,另存爲...」,然後查看默認情況下Microsoft認爲文件格式是什麼。你知道目標格式的編碼是什麼嗎? 「ANSI」是Microsoft稱之爲默認的本地化編碼。在美國版本的Windows上,它是'Windows-1252'。 –

回答

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小命令被簡化,上面展示了IO流的方法將避免您不必對整個數據文件加載到存儲器中 - 如果任何一個好處你的數據文件很大。

相關問題