Batch file 包含特殊字符的CMD替换短语

Batch file 包含特殊字符的CMD替换短语,batch-file,cmd,windows-7,Batch File,Cmd,Windows 7,我需要做一件非常简单的事情:用一个替换另一个。这必须通过CMD批处理文件(适用于Windows 7)完成。要替换的帧可以位于txt文件行中的任何位置(以及许多行) 问题是要替换的帧包含“:”和“!”字符。我对批处理文件不是很熟练(说得委婉一点),尽管我花了一些时间专门学习这个特定的问题。对我来说这看起来很复杂。最后,我无意中跳过了这个问题,但是。。。我觉得我这样做太野蛮了 应替换的frase的实际行为,例如: "21:12:45 WARNING: No video signal present!

我需要做一件非常简单的事情:用一个替换另一个。这必须通过CMD批处理文件(适用于Windows 7)完成。要替换的帧可以位于txt文件行中的任何位置(以及许多行)

问题是要替换的帧包含“:”和“!”字符。我对批处理文件不是很熟练(说得委婉一点),尽管我花了一些时间专门学习这个特定的问题。对我来说这看起来很复杂。最后,我无意中跳过了这个问题,但是。。。我觉得我这样做太野蛮了

应替换的frase的实际行为,例如:

"21:12:45 WARNING: No video signal present!"
应替换的框架为:

"WARNING: No video signal present!"
frase应替换为:

"Recognition suspended"
我发现了以下代码:

它工作得很好,除了不能与“!”一起工作,如我所见,而escape char“^”永远不工作。但我注意到,虽然它不能正常工作,但它会修剪感叹号。以下是(b)之前和(a)之后的真实字符串:

因此,我在代码中添加了另外两行,这就完成了。整个代码现在是:

@echo off
setlocal enabledelayedexpansion
set txtfile=D:\wfc\testlib\test.txt
set newfile=D:\wfc\testlib\new_test.txt
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
   set newline=%%a
   set newline=!newline:No video signal present!=!
   set newline=!newline:No video signal present=!
   set newline=!newline:WARNING:=Suspend recognition!
   echo !newline! >> %newfile%
)
第一条关键线切“!”, 第二行将“不存在视频信号”替换为“不存在”(对其进行修剪), 第三行将其余的“警告:”替换为理想的“暂停识别”

最后,我有:

(b)20:42:18 WARNING: No video signal present!
(a)20:42:18 Suspend recognition

我觉得这可以做得很优雅。此外,我不确定我的方式是否因某种原因(数据损坏等)而不危险。请帮助。

在.bat文件脚本中替换短语非常容易

powershell -NoLogo -NoProfile -Command ^
    "Get-Content -Path '.\subfrase-in.txt' |" ^
        "ForEach-Object { $_ -replace 'WARNING: No video signal present!', 'Recognition suspended' }"

是的,这样做比较容易

首先,它不是行
set newline=!换行符:不存在视频信号!=删除
字符,但它是行
set newline=%%a
,因为变量引用
%%a
展开时会启用,这发生在延迟展开之前,因此会出现一个孤立的感叹号,该感叹号会被删除

成功的关键是在扩展
%%a时禁用延迟扩展,然后启用它。在
中,不会导致任何问题;
也没有。因此,以下代码应该可以工作:

@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
设置“txtfile=D:\wfc\testlib\test.txt”
设置“newfile=D:\wfc\testlib\new\u test.txt”
>%newfile%(
对于/F usebackq^delims^=^eol^=%%a in(“%txtfile%”)do(
设置“换行符=%%a”
setlocal EnableDelayedExpansion
echo(!newline:警告:不存在视频信号!=识别已暂停!
端部
)
)
端部
退出/B
我还更改了以下项目:

  • 通过使用引号改进了的语法,避免了一些特殊字符的麻烦
  • 避免了中间变量
    换行符
    ,因此直接在
    echo
    行中进行字符串操作
  • 引用文件路径/名称以避免出现空格问题,因此使用选项
  • tokens=*
    替换为该选项,以保持前导空格;为了避免由于默认选项而丢失以
    开头的行;
    ,我使用了外观奇怪的无引号选项字符串语法,因为这是唯一一种(!)不同时定义
    delims
    eol
    的方法(您不能写入
    “delims=delims=“
    ”,因为这会将
    定义为
    eol
    字符;
    “eol=delims=“
    会定义空格,
    ”eol=delims=“
    定义
    d
  • 对于
循环,整个
,因此不需要删除初始文件,而且性能要好得多,因为输出文件只需打开和关闭一次,而不是每次迭代
  • echo Text>“file.ext”
    返回一个尾随空格(实际上是
    前面的空格);这可以通过上面的项避免;通常,在使用反向重定向语法
    “file.ext”echo Text
    时可以避免
  • echo!VAR!
    返回
    echo处于打开|关闭状态。
    如果变量
    VAR
    为空,则使用外观奇特但安全的语法
    echo(!VAR!
  • 启用延迟扩展时避免立即(
    %
    )扩展,以避免丢失

  • 要保留原始文件中出现的空行,请将代码更改为:

    @echo关闭
    setlocal EnableExtensions DisableDelayedExpansion
    设置“txtfile=D:\wfc\testlib\test.txt”
    设置“newfile=D:\wfc\testlib\new\u test.txt”
    >%newfile%(
    对于/F“delims=“%%a in('findstr/N/R“^”“%txtfile%”)do(
    设置“换行符=%%a”
    setlocal EnableDelayedExpansion
    设置“换行符=!换行符:警告:不存在视频信号!=识别暂停!”
    回音(!换行:=!
    端部
    )
    )
    端部
    退出/B
    

    用于以行号加冒号作为输入文件每行的前缀(
    /N
    选项)。然后子字符串替换完成。最后,包括第一个
    在内的所有内容都将被删除,因此行号前缀将被删除。

    怀疑OP被否决。可能是因为您说的是批处理文件,然后使用poweshell?是的,您可以批处理powershell,但为什么不单独使用powershell呢?我同意单独使用PowerShell,但OP指定必须“通过CMD批处理”完成。“有些人不介意使用
    find.exe
    taskkill.exe
    、或
    net.exe
    ,但不愿使用
    powershell.exe
    。这只是机器上的另一个命令。为什么不应该使用它呢?我只是在想投票失败的原因。也许只是指定批量包装powershell命令。
    “usebackq tokens=*
    是一个糟糕的选择,因为它会去掉前导空格和制表符。最好使用
    powershell -NoLogo -NoProfile -Command ^
        "Get-Content -Path '.\subfrase-in.txt' |" ^
            "ForEach-Object { $_ -replace 'WARNING: No video signal present!', 'Recognition suspended' }"