我正在尝试编写一个程序来创建一个文件,将文件的内容回显到新文件中。例如:
如果我有一个名为 foo.txt 的文件,其内容为:
@echo off
echo Hello World
pause
exit
该文件将创建一个单独的文件,其中包含以下内容:
@echo off
color a> foo2.txt
echo @echo off>> foo2.txt
echo echo Hello World>> foo2.txt
echo pause>> foo2.txt
echo exit>> foo2.txt
但是,我遇到了一个问题。如果我在文件中添加感叹号:
@echo off
echo Hello World!
pause
exit
文件中不会包含感叹号。
我该如何解决这个问题?
我的代码:
@echo off
setlocal enabledelayedexpansion
:input
set /p "input=Input Filename: "
if not exist "%input%" goto input
cls
set /p "output=Output Filename: "
cls
echo @echo off> "%input%-Echo.bat"
echo color a^> "%output%">> "%input%-Echo.bat"
for /f "usebackq delims=" %%A in ("%input%") do (
set "line=%%A"
set "line=!line:^=^^!"
set "line=!line:<=^<!"
set "line=!line:>=^>!"
set "line=!line:&=^&!"
set "line=!line:|=^|!"
set "line=!line:(=^(!"
set "line=!line:)=^)!"
set "line=!line:%%=%%%%!"
echo(echo !line! ^>^> "%output%" >> "%input%-Echo.bat"
)
echo The process has been completed. The file is called "%input%-Echo.bat"
echo.
<nul set /p=Press any key to exit . . .
pause>nul
exit
以下批处理文件通过将从文件读取的行分配给环境变量
Line
后启用延迟变量扩展来解决带有感叹号的行的错误处理问题。改进的代码句柄还可以纠正空行,但不会删除它们。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
:PromptInputFile
set "InputFile="
set /P "InputFile=Input file name: " || goto PromptInputFile
set "InputFile=%InputFile:"=%"
if not defined InputFile goto PromptInputFile
if not exist "%InputFile%" goto PromptInputFile
if exist "%InputFile%\" goto PromptInputFile
cls
:PromptOutputFile
set "OutputFile="
set /P "OutputFile=Output file name: " || goto PromptOutputFile
set "OutputFile=%OutputFile:"=%"
if not defined OutputFile goto PromptOutputFile
if exist "%OutputFile%\" goto PromptOutputFile
cls
for %%I in ("%InputFile%") do set "BatchFileFull=%%~dpnI-Echo.cmd" & set "BatchFileName=%%~nI-Echo.cmd"
(echo @echo off
echo echo @color a^>"%OutputFile%"
for /F "delims=" %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%InputFile%" 2^>nul') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if defined Line (
set "Line=!Line:^=^^!"
set "Line=!Line:<=^<!"
set "Line=!Line:>=^>!"
set "Line=!Line:&=^&!"
set "Line=!Line:|=^|!"
set "Line=!Line:(=^(!"
set "Line=!Line:)=^)!"
set "Line=!Line:%%=%%%%!"
echo(echo !Line! ^>^>"!OutputFile!"
) else echo echo(^>^>"!OutputFile!"
endlocal
))>"%BatchFileFull%"
echo The process has been completed. The file is called: "%BatchFileName%"
echo(
set /P "=Press any key to exit . . . "<nul
pause>nul
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
cls /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
pause /?
set /?
setlocal /?
另请参阅:
一些补充说明:
不带选项
exit
的命令 /B
在批处理文件末尾几乎不需要,并且如果用户从命令提示符窗口中运行批处理文件而不是双击批处理文件,则会适得其反。文件管理器,例如 Windows 文件资源管理器 或 Total Commander。在开发过程中调试批处理文件也会适得其反。例外情况是批处理文件,用于从 GUI 安装程序可执行文件启动的安装过程,批处理文件会使用最后一个命令行删除自身。
使用
>>
会导致cmd.exe
打开已存在的输出文件并寻找文件末尾,或者在不存在的情况下创建文件,附加文本并关闭文件。将每一行写入文件中都这样做是非常低效的。它甚至可能导致输出文件不包含所有行,因为防病毒应用程序会打开输出文件以扫描恶意代码,然后关闭文件并再次打开它以附加防病毒应用程序的下一行防止。上面的批处理代码仅打开一次由 cmd.exe
引用的文件,并覆盖可能已经存在的同名文件,附加在以 %BatchFileFull%
开头并以 (
结尾的命令块中使用的任何命令 ECHO的所有文本输出最后关闭文件。如果已经存在这样一个设置了只读属性的文件,或者用户没有创建和写入该文件的必要权限,或者存在与要创建的文件同名的目录(不太可能),则此操作可能会失败)或要创建的文件已存在并由另一个应用程序打开,从而阻止通过
)
打开它。
具有特殊含义的字符的转义。字符 cmd.exe
在双引号参数字符串内由
^<>&|()
按字面解释。像这样的命令行
cmd.exe
在输入文件中变成
%SystemRoot%\System32\findstr.exe /I /R "^Error" %SystemRoot%\*.log
在
echo %%SystemRoot%%\System32\findstr.exe /I /R "^^Error" %%SystemRoot%%\*.log >>"ListErrors.cmd"
文件中生成输出文件
*-Echo.cmd
和 ListErrors.cmd
并且正则表达式在 Windows 目录中的所有
%SystemRoot%\System32\findstr.exe /I /R "^^Error" %SystemRoot%\*.log
文件中不再找到以
Error
开头的不区分大小写的行作为输入文件中的命令行,因为搜索中是 .log
而不仅仅是 ^^
表达。