batch:添加unicode标头或如何添加十六进制值或其他任何方式?

时间:2013-11-01 10:50:25

标签: batch-file unicode

我有一个使用拖放的批处理脚本,并根据删除的文件/文件夹的文件名创建一些html代码。 随着

chcp 65001

我得到这个写unicode。一切都很好。至少在记事本编辑器中,虽然浏览器只显示垃圾。当我在记事本中重新保存文件时,该文件在浏览器中也可以正常工作。 不幸的是,创建的unicode文件似乎缺少两个“unicode header”字符(0xFF和0xFE),就在文件之前,因为与hexdump(http://www.fileformat.info/tool/hexdump.htm)的比较产生了结果。

关于这个话题,我发现了这个: http://www.robvanderwoude.com/type.php#Unicode

来自那里的链接文件不起作用(参数格式错误)来自非本地回声等的此站点的示例是不可能的。复制一个空的unicodeHeader-Helper文件并附加我的文件工作正常,但是非常不理想,因为它意味着,任何文件夹,我的文件被拖动和下载都需要有这个帮助文件。这不是假设的因为它不切实际,所以这是不好的。

使用类型也是不可能的,因为它在字符之间创建了大量的空格。

所以我考虑将缺少标题的文件写入临时文件,将两个十六进制值添加到文件中并将临时文件附加到该文件中。所以基本上直接编写十六进制字符而不是从空的unicode帮助文件中复制它们。

我发现了这个: http://www.dostips.com/forum/viewtopic.php?f=3&t=3857 而且这个: Writing characters > 7F (127) as hex strings according to code page 1252 in windows batch file

我以为我可以将示例十六进制值替换为0xFF和0xFE并使其回显到文件:

@echo off
call :hex2Char 0xFF char_FF
call :hex2Char 0xFE char_FE
echo %char_FF% %char_800%
exit /b

:hex2Char  hexString  rtnVar
  for /f delims^=^ eol^= %%A in (
    'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(%~1"'
  ) do set "%~2=%%A" >> temp.txt 
exit /b

但它似乎并不那么简单。由此产生的两个问题: 1.它在那里写了一些unicode字符,但它与unicode助手文件不同,正如hexdump所示。

file name: UniHeader.txt
mime type: 

0000-0003:  ef bb bf                                   


file name: temp.txt
mime type: 

0000-0000:                                                   

实际上我可以更改FF或FE,它仍然只在hexdump输出中打印0000-0000 ...

  1. 我可以在该文件后添加我想要的任何内容(比如编写无标题文件的代码并将其附加到创建的文件中,代码在第二个出口/ b处停止并且不再写任何内容。(但是删除它使整个事情根本不起作用并将其移动到文件的末尾使它无法找到被放到蝙蝠上的文件) 老实说,我目前还没有通过这几个代码。 exit / b标记命令的结束,如果我正确地得到它,那么,为什么它在第一个退出/ b之后继续工作,但是在第二个出口/ b处停止?我也尝试使用标签和goto,但没有用。
  2. 我现在不知所措。有没有优雅的方法来解决这个问题?

3 个答案:

答案 0 :(得分:4)

您可以在批处理脚本中嵌入base64编码的部分,该部分将创建一个2字节的文件,然后使用copy /b "my_header_file.bin" + "myfile.html" newfile.htm"将目标文件添加到其中。

它使用certutil进行解码(并使用-encode来创建文本部分的certutil),因此需要Vista及更高版本。

以下是创建包含hex:FF FE

的头文件的脚本
@echo off
(
echo -----BEGIN CERTIFICATE-----
echo //4=
echo -----END CERTIFICATE-----
)>header.tmp
certutil -decode -f header.tmp "my_header_file.bin" >nul
del header.tmp

copy /b "my_header_file.bin" + "myfile.html" "newfile.html"
move /y "newfile.htm" "myfile.html" >nul
del "my_header_file.bin"

答案 1 :(得分:1)

将它们包含在批处理文件中。

@echo off

    for /f "tokens=2 delims=:" %%f in ('findstr /b /c:"BOFM:" "%~dpnx0"') do echo %%f

exit /b
rem Here starts the special characters part
BOFM:ÿþ:

以BOFM开头的行:输入为ALT + charchode以获取所需的字符。

已编辑 -

我放弃了。我无法使其与批处理文件,数据文件和编辑器中的多个页面代码保持一致。无法保证将生成什么。所以,我拿@foxidrive回答(真棒!)来生成文件前缀并尝试。

我发现如果我们使用FF FE作为cmd生成的文件的前缀,而不是unicode模式(/u参数)但是使用unicode页面代码(65001),我们正在生成一个标记为unicode(前缀)的文件,但内容不是,我们每个字符只生成一个字节。所以我们得到了#34;中文"?字符,只是将单字节字符流转换为两个字节字符。

如果我们使用相同的前缀但是来自unicode cmd(带有/u参数)和unicode页面代码(65001),那么会生成一个真正的unicode文件,并且从命令行,记事本中正确显示内容和浏览器(在ie和firefox中测试)。但这是一个真正的unicode文件,因此每个字符生成两个字节。

我们可以从非unicode cmd发送utf8 BOM FF FE而不是EF BB BF,而是使用unicode页码。这会生成一个带有BOM前缀的utf8,一个或多个字节用于字符(取决于每个字符的utf编码),它在编辑器和浏览器中正确显示,但不能在命令行中显示。

我正在尝试的代码(改编自OP附加文件)(从非unicode cmd运行):

@echo off

    if ["%~1"]==[""] goto :EOF

    setlocal enableextensions enabledelayedexpansion

    rem File to generate
    set "myFile=aText.txt"

    rem save current pagecode
    for /f "tokens=2 delims=:" %%f in ('chcp') do set "cp=%%f"

    rem Generate BOM
    call :generateBOM "%myFile%"

    rem change to unicode 
    chcp 65001 > nul 

:loop
    echo %1 >> "%myFile%"
    for %%a in ("%1") do (
        echo %%~nxa 
        echo   ^<br^>^<img src='%%~nxa'^>^<br^> 
    ) >> "%myFile%"

    shift
    if ["%~1"]==[""] goto showData
    goto loop   

:showData

    "%myFile%"

:endProcess
    rem Cleanup and restore pagecode
    endlocal & chcp %cp% > nul 

    exit /b 

:generateBOM file
    rem [ EF BB BF ] utf8 bom     encoded value = 77u/
    rem [ FF FE ]    unicode bom  encoded value = //4=
    echo 77u/>"%~1"

    rem Yes, certutil allows decode inplace, so no temporary file needed
    certutil -f -decode "%~1" "%~1" >nul

    endlocal
    goto :EOF

答案 2 :(得分:1)

您可以按0xFF 0xFE

创建Unicode标头(CertUtil -decodehex
rem // Create hexadecimal-encoded file:
> "header.tmp" (echo FF FE)
rem // Decode file to binary header file:
> nul CertUtil -f -decodehex "header.tmp" "header.tmp"

rem // Combine binary header file and Unicode text file:
copy /B "header.tmp" + "U-file.txt" "header.tmp"
rem // Move combined file over original Unicode text file:
move /Y "header.tmp" "U-file.txt"

使用forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo(0xFF0xFE"的方法存在问题,因为echo会产生尾随换行符。 echo(0xFF0xFE的替代方法是< nul set /P ="0xFF0xFE",但这也不起作用,因为set /P会从消息文本中删除前导空格,并且0xFF被视为此类内容(它不幸的是,这是一个不间断的空间。