我需要做一件非常简单的事:用另一个替换一个frase。这必须由CMD批处理文件(对于Windows 7)完成。要被替换的frase可以位于txt文件行中的任何位置(并且在许多行中)。
问题是要替换的frase包含“:”和“!”字符。我对批处理文件不是很熟练(说得温和一点),虽然我花了几个小时来特别了解这个具体问题。对我来说这看起来很复杂。最后,偶然的,我覆盖了这个问题,但是......我觉得我做的很野蛮。
应该替换的frase的实际行是例如:
"21:12:45 WARNING: No video signal present!"
应该替换的frase是:
"WARNING: No video signal present!"
应该替换的frase是:
"Recognition suspended"
我找到了这段代码:https://www.computerhope.com/forum/index.php?topic=41188.0
它工作正常,但不能用“!”正如我所见,逃避char“^”永远不会奏效。但我注意到虽然它不能正常工作 - 它会修剪感叹号。以下是(b)之前和(a)之后的真实字符串:
(b)20:42:18 WARNING: No video signal present!
(a)20:42:18 WARNING: No video signal present
所以我在代码中添加了2个其他行,这样就完成了。整个代码现在是:
@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
我觉得这可以优雅地完成。此外,我不确定,如果我的方式由于某种原因(数据损坏等)没有危险。请帮忙。
答案 0 :(得分:1)
是的,这可以更轻松。
首先,删除set newline=!newline:No video signal present!=!
字符的行!
不是行set newline=%%a
,而是%%a
行,因为在{%%a
时启用了delayed variable expansion {3}}变量引用:
已展开,在延迟扩展之前发生,因此会出现一个孤立的感叹号,只是被移除。
成功的关键是在!
扩展期间禁用延迟扩展并在之后启用它。在for
中,@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "txtfile=D:\wfc\testlib\test.txt"
set "newfile=D:\wfc\testlib\new_test.txt"
> "%newfile%" (
for /F usebackq^ delims^=^ eol^= %%a in ("%txtfile%") do (
set "newline=%%a"
setlocal EnableDelayedExpansion
echo(!newline:WARNING: No video signal present!=Recognition suspended!
endlocal
)
)
endlocal
exit /B
不会导致任何问题;搜索字符串中的newline
也不是,因为它不是第一个字符。所以下面的代码应该可以工作:
echo
我还更改了以下项目:
tokens=*
,直接在;
行中进行字符串操作; set
选项; delims
替换为usebackq
选项,以保持领先的空格;为了避免由于默认delims=
选项而丢失以eol
开头的行,我使用了奇怪的不带引号的选项字符串语法,因为这是唯一的方式(!)没有{{1}和"delims= eol="
同时定义(你不能写"
因为这会将eol
定义为"eol= delims="
字符; "eol=delims="
会定义 SPACE 和d
for
); eol
整个echo Text > "file.ext"
循环,因此不需要删除初始文件,性能要好得多,因为输出文件必须只打开和关闭一次,而不是每次迭代; < / LI>
>
返回一个尾随的空格(实际上是> "file.ext" echo Text
前面的那个);上述项目可以避免这种情况;通常,使用反向重定向语法echo !VAR!
; ECHO is on|off.
为空,则VAR
会返回echo(!VAR!
;为了避免这种或其他意外的输出,使用奇怪但安全的语法%
; !
)扩展,以避免丢失@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "txtfile=D:\wfc\testlib\test.txt"
set "newfile=D:\wfc\testlib\new_test.txt"
> "%newfile%" (
for /F "delims=" %%a in ('findstr /N /R "^" "%txtfile%"') do (
set "newline=%%a"
setlocal EnableDelayedExpansion
set "newline=!newline:WARNING: No video signal present!=Recognition suspended!"
echo(!newline:*:=!
endlocal
)
)
endlocal
exit /B
; 要保留原始文件中显示的空行,请将代码更改为:
/N
redirected用于为输入文件的每一行添加一个行号加冒号(:
选项)。然后完成子串替换。最后,所有内容都包括第一个{{1}},因此行号前缀将被删除。
答案 1 :(得分:0)
在.bat文件脚本中替换短语非常容易。
powershell -NoLogo -NoProfile -Command ^
"Get-Content -Path '.\subfrase-in.txt' |" ^
"ForEach-Object { $_ -replace 'WARNING: No video signal present!', 'Recognition suspended' }"