[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 aloha20200628 于 2024-5-12 16:14 编辑

回复 9# 娜美

楼主随便看看有关‘文件编码识别’为何至今未有终解的网页论述即知其中一二了...
好吧再给一个简单版本,就用本坛可下载的coder.exe置换3楼代码中的uchardet.exe,因前者不排查非文本文件类型故可使3楼代码进一步简化...
有劳powershell用.net的[io.file]方法,把utf-8/utf-8+BOM‘兄弟俩’一锅烩了,把utf-16be/utf-16le‘兄弟俩’也一锅烩了,为码农省事了...
  1. @echo off &setlocal &del /q "allinOne.txt" "bug.txt" 2>nul
  2. for /f "delims=" %%F in (b.txt) do if not exist "%%~F" (echo,"badFile -- %%F"&echo,%%F>>"bug.txt") else (
  3. for /f "tokens=1 delims=_" %%a in (' coder.exe -s -a gc -f "%%~F" ') do (
  4. echo, /// %%~F ///>>"allinOne.txt"
  5. if /i "%%a"=="utf-8" (
  6. powershell "$s=[io.file]::readalllines('%%~F',[text.encoding]::utf8);[io.file]::appendalllines('allinOne.txt',$s,[text.encoding]::default)"
  7. ) else if /i "%%a"=="utf-16" (
  8. powershell "$s=[io.file]::readalllines('%%~F',[text.encoding]::unicode);[io.file]::appendalllines('allinOne.txt',$s,[text.encoding]::default)"
  9. ) else if /i "%%a"=="ansi" (more "%%~F">>"allinOne.txt")
  10. )
  11. echo,>>"allinOne.txt"
  12. )
  13. endlocal&pause&exit/b
复制代码

TOP

本帖最后由 娜美 于 2024-5-9 14:45 编辑

回复 3# aloha20200628


   aloha20200628 大哥哥,是不是似乎还可以做些优化 ?  uchardet.exe 它现在需要读完所有文本才能检测出编码, 这似乎要浪费这些没用的时间过程(因为要从头到尾读一遍)   

但是, 如果让它只读文本的前几行就能判断文本编码, 这是不是会更好 ?

TOP

本帖最后由 娜美 于 2024-5-9 21:42 编辑

O K 谢 谢  thanks

TOP

本帖最后由 娜美 于 2024-5-9 11:11 编辑

回复 6# czjt1234


   大哥哥, 小文本可以没有问题 , 结果倒是正确, 只是有点慢,。它似乎是读写进内存去处理, 如果是有稍大一点文件, 会使内存挤满, 如果挤满了内存等很久都没出结果

TOP

回复 4# 娜美


    运行结果反馈下,看看有没有问题

QQ 20147578

TOP

回复 3# aloha20200628


   大哥哥 thanks 如果用poweshell可以直接合并所有文本应该是最直接的, 不用管它们是什么编码。 不做所有文件编码判断,  如果用的poweshell合并应该也不会出啥问题  另外poweshell合并时还可以提高一下速度吗

TOP

谢谢2位大哥哥thanks

TOP

本帖最后由 aloha20200628 于 2024-5-12 16:16 编辑

回复 1# 娜美

        powershell确实为转换文件编码提供了.net资源中可靠而高效的方法,但未能直接提供准确率较高的文件编码‘推测’方法。目前已被业界广为采用的文件编码‘推测’方法是源自火狐(firefox)提供的开源代码(如python/c#/java等已均有成熟的接口),还可从有关网站下载其专门编译好的命令行实用工具。如果已经安装了python环境及其chardetect应用,即可直接在其安装主目录下找到...\Scripts\chardetect.exe,用其在命令行直接运行即可获取指定文本文件的编码‘推测’结果。另一个便捷方法是从网址》https://github.com/JetDemo/uchardet 下载源自火狐开源代码采用c++编译好的命令行实用工具 uchardet.exe。
        以下给出的批处理代码就是利用uchardet.exe的‘推测’结果,据此调用powershell的[io.file]方法,实现 utf-8/utf-8+BOM/utf-16le/utf-16be 到简中编码(gb2312)的高速转换,顺便修复了源文件中的unix换行符,生成最终结果文件allinOne.txt。代码中另外附加了文件名分隔标注行,如不需要可删除第4行。
  1. @echo off &setlocal &del /q "allinOne.txt" "bug.txt" 2>nul
  2. for /f "delims=" %%F in (b.txt) do if not exist "%%~F" (echo,"badFile -- %%F"&echo,%%F>>"bug.txt") else (
  3. for /f "tokens=1-2 delims=-" %%a in (' uchardet.exe "%%~F" ') do (
  4. if /i "%%a" neq "unknown" (echo, /// %%~F ///>>"allinOne.txt")
  5. if /i "%%a"=="utf" if "%%b"=="8" (
  6. powershell "$s=[io.file]::readalllines('%%~F',[text.encoding]::utf8);[io.file]::appendalllines('allinOne.txt',$s,[text.encoding]::default)"
  7. ) else if /i "%%a"=="utf" if "%%b"=="16" (
  8. powershell "$s=[io.file]::readalllines('%%~F',[text.encoding]::unicode);[io.file]::appendalllines('allinOne.txt',$s,[text.encoding]::default)"
  9. )
  10. if /i "%%a"=="ascii" (
  11. more "%%~F">>"allinOne.txt"
  12. ) else if /i "%%a"=="gb18030" (
  13. more "%%~F">>"allinOne.txt"
  14. ) else if /i "%%a"=="unknown" (
  15. echo,"unknown -- %%F"&echo,%%F>>"bug.txt"
  16. )
  17. )
  18. echo,>>"allinOne.txt"
  19. )
  20. endlocal&pause&exit/b
复制代码
1

评分人数

    • 77七: 感谢分享, uchardet好用!技术 + 1

TOP

powershell不熟悉,vbs来一个
  1. Const b_txt    = "b.txt"
  2. Const out_text = "all.tmp"
  3. Const FailName = "bug.txt"
  4. Set oFSO = CreateObject("Scripting.FileSystemObject")
  5. Set oTextStream1 = oFSO.OpenTextFile(out_text, 2, True)
  6. Set oTextStream2 = oFSO.OpenTextFile(FailName, 2, True)
  7. Set oStream = CreateObject("ADODB.Stream")
  8. oStream.Type = 2    'adTypeText
  9. oStream.Mode = 3    'adModeReadWrite
  10. oStream.Charset = "GBK"
  11. oStream.Open()
  12. oStream.LoadFromFile b_txt
  13. arr = Split(oStream.ReadText(), vbCrLf)
  14. oStream.Close()
  15. For Each i In arr
  16.     If oFSO.FileExists(i) Then
  17.         oStream.Charset = checkCharset(i)
  18.         oStream.Open()
  19.         oStream.LoadFromFile i
  20.         s = oStream.ReadText()
  21.         oStream.Close()
  22.         s = RePlace(s, vbCrLf, vbCr)
  23.         s = RePlace(s, vbLf, vbCr)
  24.         s = RePlace(s, vbCr, vbCrLf)
  25.         oTextStream1.WriteLine s & vbCrLf
  26.     Else
  27.         oTextStream2.WriteLine i
  28.     End If
  29. Next
  30. MsgBox "ok"
  31. Function checkCharset(ByVal file)
  32.     Dim oStream, oRegExp, arr(), s
  33.     Set oStream = CreateObject("ADODB.Stream")
  34.     oStream.Type = 1    'adTypeBinary
  35.     oStream.Mode = 3    'adModeReadWrite
  36.     oStream.Open()
  37.     oStream.LoadFromFile file
  38.     If oStream.Size >= 2 Then
  39.         s = Hex(AscB(oStream.Read(1)))
  40.         s = s & Hex(AscB(oStream.Read(1)))
  41.         If s = "FFFE" Or s = "FEFF" Then
  42.             checkCharset = "Unicode"
  43.             Exit Function
  44.         End If
  45.     End If
  46.     oStream.Position = 0
  47.     ReDim arr(oStream.Size - 1)
  48.     For s = 0 To oStream.Size - 1
  49.         arr(s) = ChrW(AscB(oStream.Read(1)))
  50.     Next
  51.     oStream.Close()
  52.     s = "[\xC0-\xDF]([^\x80-\xBF]|$)"        & _
  53.         "|[\xE0-\xEF].{0,1}([^\x80-\xBF]|$)" & _
  54.         "|[\xF0-\xF7].{0,2}([^\x80-\xBF]|$)" & _
  55.         "|[\xF8-\xFB].{0,3}([^\x80-\xBF]|$)" & _
  56.         "|[\xFC-\xFD].{0,4}([^\x80-\xBF]|$)" & _
  57.         "|[\xFE-\xFE].{0,5}([^\x80-\xBF]|$)" & _
  58.         "|[\x00-\x7F][\x80-\xBF]"            & _
  59.         "|[\xC0-\xDF].[\x80-\xBF]"           & _
  60.         "|[\xE0-\xEF]..[\x80-\xBF]"          & _
  61.         "|[\xF0-\xF7]...[\x80-\xBF]"         & _
  62.         "|[\xF8-\xFB]....[\x80-\xBF]"        & _
  63.         "|[\xFC-\xFD].....[\x80-\xBF]"       & _
  64.         "|[\xFE-\xFE]......[\x80-\xBF]"      & _
  65.         "|^[\x80-\xBF]"
  66.     Set oRegExp = New RegExp
  67.     oRegExp.MultiLine = False
  68.     oRegExp.Pattern = s
  69.     checkCharset = "GBK"
  70.     If Not oRegExp.Test(Join(arr, "")) Then checkCharset = "UTF-8"
  71. End Function
复制代码

QQ 20147578

TOP

返回列表