我的代码有问题...
我有文件t1.txt和t2.txt。目标是将具有相同内容的文件1移到文件2,除非它包含特定的单词,在这种情况下,必须用预定义的单词替换整行。
具体地说,我对'if'和变量的重新分配有疑问。
@echo off
setlocal enabledelayedexpansion
set p1=t1.txt
set p2=t2.txt
for /f "tokens=*" %%a in (%p1%) do (
set nl=%%a
if not "%n1%"=="%n1:texto=%" (
set n1=replace with this text
)
echo !n1! >> %p2%
)
pause>nul
exit
答案 0 :(得分:1)
使用纯批处理脚本可以完成您的任务,但是对于某些特殊字符并且不丢失原始文件的空行,以安全的方式进行任务并不是那么简单。所以这是一种方法:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IFILE=t1.txt" & rem // (input file to be processed)
set "_OFILE=t2.txt" & rem // (output file to be returned)
set "_WORD=\<texto\>" & rem // (string to search in lines, `findstr` regular expression)
set "_REPL=replace with this text" & rem // (text to replace lines containing the word)
rem // Output to console if no output file is provided:
if not defined _OFILE set "_OFILE=con"
rem /* Initialise a loop counter which should be synchronous to the line number, unless
rem a line matches the search string, so it becomes skipped and the numbers differ: */
set /A "LCNT=0"
rem // Write to output file:
> "%_OFILE%" (
rem /* Read from input file, prefix every line by a line number + `:`, skip lines
rem matching the search string: */
for /F delims^=^ eol^= %%L in ('cmd /V /C findstr /V /N /R /C:"!_WORD!" "!_IFILE!"') do (
rem // Split off the line number from the line string:
for /F "delims=:" %%K in ("%%L") do (
rem // Increment loop counter:
set /A "LCNT+=1"
rem // Store current line (including line number prefix):
set "LINE=%%L"
rem // Toggle delayed expansion in order to avoid trouble with `!`:
setlocal EnableDelayedExpansion
rem // Check whether loop counter and line number differ:
if !LCNT! lss %%K (
rem /* Numbers differ, hence return the replace line as many times
rem as the difference is: */
set /A "DIFF=%%K-LCNT"
for /L %%D in (1,1,!DIFF!) do echo(!_REPL!
)
rem // Return line with line number prefix removed:
echo(!LINE:*:=!
endlocal
rem // Synchronise loop counter with line number:
set "LCNT=%%K"
)
)
)
endlocal
exit /B
限制:
答案 1 :(得分:0)
命令 FOR 始终忽略空行,默认情况下,它也忽略以分号开头的行。在使用延迟扩展时,还会在循环中执行命令行set nl=%%a
时修改包含感叹号的行。因此,根据文件t1.txt
的内容,使用 FOR 的解决方案可能是完全错误的尝试。
下载由 Dave Benham 编写的JREPL.BAT,这是一个批处理文件/ JScript混合程序,可使用JScript在文件上运行正则表达式替换并将其存储在与以下批处理文件相同的目录中
@echo off
if not exist "%~dp0jrepl.bat" goto :EOF
if not exist "t1.txt" goto :EOF
call "%~dp0jrepl.bat" "^.*textto.*$" "replace with this text" /F "t1.txt" /O "t2.txt"
rem Compare the two files binary with ignoring the differences. Delete file
rem t1.txt if a line was modified by JREPL.BAT. Otherwise move file t1.txt
rem over t2.txt to keep the last modification date of file t1.txt for t2.txt.
%SystemRoot%\System32\fc.exe /B "t1.txt" "t2.txt" >nul
if errorlevel 1 ( del "t1.txt" ) else move /Y "t1.txt" "t2.txt"
jrepl.bat
使用正则表达式搜索包含textto
的行,并将所有这些行替换为replace with this text
。将所有其他行从输入文件t1.txt
未经修改地复制到输出文件t2.txt
。
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
call /?
del /?
echo /?
fc /?
goto /?
if /?
move /?
rem /?
jrepl.bat /?