【问题标题】:Trying to replace ; with ASCII control characters in a txt file by using a cmd file试图替换;使用 cmd 文件在 txt 文件中使用 ASCII 控制字符
【发布时间】:2016-12-24 16:19:50
【问题描述】:

我正在尝试编写一个 .cmd 文件来获取一个文本文件并在每行的开头添加一个字符串,将所有分号替换为 ASCII 控制代码 30 (RS),并以 RS 结束每一行ASCII 码 31(美国)。当我将 RS 和 US 放入文件时,笔记本不会保存它,除非它是 Unicode,但是当我尝试以 Unicode 运行它时,它不会运行。

这是我所拥有的不起作用的:

@echo on > Convert.txt & setLocal enableDELAYedexpansion

set old=;
set new=▲
set bgnstr=@TESTSTATS▲▲▲
set endstr=▲▼

for /f "tokens=* delims= " %%a in (test1.txt) do (
set str=%%a
set str=%BGNSTR%!str:%old%=%new%!%endstr%
>> Convert.txt echo !str!
)

如果我用任何其他字符代替 RS/US,它会做我想做的事。

【问题讨论】:

  • for /f "tokens=* delims= " 定义一个空格作为分隔符;连同标记*,这将删除前导空格(但不删除制表符);你想要那个吗?
  • 在我要转换的文件中,每个字符串都在自己的行上,所以我的工作正常。

标签: windows batch-file text unicode ascii


【解决方案1】:

您的脚本应该可以按预期工作,但 不是 ASCII 控制代码:

▲    U+25B2    Black Up-Pointing Triangle
▼    U+25BC    Black Down-Pointing Triangle

不幸的是,ASCII 控制码 30 (RS) 和 ASCII 码 31 (US) 在这里都不可见;因此从十六进制编辑器插入下一个屏幕截图。在下一个脚本中,bgnstr 变量会稍微缩短,以使mycharmap.bat 脚本的下一个输出保持在可接受的长度内。

@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
set old=;
set "new="
set "bgnstr=@TS"
set "endstr="
> Convert.txt (
  for /f "tokens=* delims= " %%a in (test1.txt) do (
    set str=%%a
    set str=%BGNSTR%!str:%old%=%new%!%endstr%
    echo !str!
  )
)

输入/输出

==> type test1.txt
a;b;c
d;e;f;
h;i;j

==> D:\bat\SO\39006271.bat

==> type Convert.txt
@TSabc
@TSdef
@TShij

ASCII 控制码在type Convert.txt 的输出中不可见; 下一个代码中的mycharmap.bat 脚本和以下屏幕截图显示了它们。 mycharmap.bat 脚本来自我在 superuser.com 上的回答:Full description of Windows Alt+x codes

==> for /F "skip=2 delims=" %G in ('type Convert.txt') do @mycharmap.bat "'%G'"
Ch Unicode    Alt?    CP    IME    Alt   Alt0    IME 0405/cs-CZ; CP852; ANSI 1250

 @  U+0040      64         …64…     64    064    Commercial At
 T  U+0054      84         …84…     84    084    Latin Capital Letter T
 S  U+0053      83         …83…     83    083    Latin Capital Letter S
    U+001E                 …30…           030    Information Separator Two
    U+001E                 …30…           030    Information Separator Two
    U+001E                 …30…           030    Information Separator Two
 h  U+0068     104        …104…    104   0104    Latin Small Letter H
    U+001E                 …30…           030    Information Separator Two
 i  U+0069     105        …105…    105   0105    Latin Small Letter I
    U+001E                 …30…           030    Information Separator Two
 j  U+006A     106        …106…    106   0106    Latin Small Letter J
    U+001E                 …30…           030    Information Separator Two
    U+001F                 …31…           031    Information Separator One
 @TShij

【讨论】:

    【解决方案2】:

    JosefZ 解释了箭头字符是什么,并在his answer 中提供了一个可行的解决方案。

    我想向您展示一种在运行时生成 ASCII 字符 RS (0x1E) 和 US (0x1F) 的方法,因此您无需使用十六进制将它们嵌入到批处理文件中。编辑。诀窍是使用forfiles 及其转换十六进制的能力。出现在命令字符串参数中的格式为0xHH 的字符代码(例如,0x09 将在执行命令字符串之前替换为制表符);在命令提示符窗口中键入forfiles /? 并阅读/C 参数的说明。请注意,此方法不适用于所有 ASCII 控制字符。

    所以这里是代码,包含几个解释性备注(rem):

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem /* Store RS and US characters in variables `RS` and `US`, respectively: */
    for /F %%A in ('forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo 0x1E"') do set "RS=%%A"
    for /F %%A in ('forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo 0x1F"') do set "US=%%A"
    
    rem // The above generated characters are used here:
    set "old=;"
    set "new=%RS%"
    set "bgnstr=@TS%RS%%RS%%RS%"
    set "endstr=%RS%%US%"
    
    rem // A single redirection is used to avoid multiple file accesses:
    > "Convert.txt" (
        rem /* The option string has been modified in order to reflect every line
        rem    as it appears in the file; not that empty lines still get lost: */
        for /F usebackq^ delims^=^ eol^= %%A in ("test1.txt") do (
            set "str=%%A"
            rem // Toggle delayed expansion to not lose exclamation marks:
            setlocal EnableDelayedExpansion
            echo(%bgnstr%!str:%old%=%new%!%endstr%
            endlocal
        )
    )
    
    endlocal
    exit /B
    

    【讨论】:

      猜你喜欢
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 1970-01-01
      相关资源
      最近更新 更多