这是一个非常基本的批处理脚本。这是我第一天处理这个话题。
我想创建一个脚本,它以目录名和扩展名作为参数,如果该目录存在,则具有该扩展名的每个文件的内容将被写入另一个文件中。
示例:
scripts (DIR)
|
----->myFirstBatch.bat
----->scripts2 (DIR)
|
----->test.xyz, test2.xyz, concat.txt
假设我的批处理脚本名为
myFirstBatch.bat
。
我会这样运行:
myFirstBatch scripts2 .xyz
我希望
concat.txt
有test.xyz
和test2.xyz
的内容。
这是我的脚本:
set var=%2
shift
if exist %0 (
type .\%0\*%var%>>concat.txt
)
但是里面什么都没有
concat.txt
。
我做错了什么?
文件内容复制任务可以通过以下方式完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
echo(
if "%~1" == "" echo INFO: %~n0 must be called with directory name as first parameter.& exit /B
if "%~2" == "" echo INFO: %~n0 must be called with file extension as second parameter.& exit /B
pushd "%~dp0%~1" 2>nul || (echo ERROR: Directory not found: "%~dp0%~1"& exit /B)
set "FileExtension=%~2"
if not "%FileExtension:~0,1%" == "." set "FileExtension=.%FileExtension%"
del /A /F "concat.txt" 2>nul
if exist "*%FileExtension%" (
copy /B "*%FileExtension%" "concat.txt" >nul
echo INFO: Copied files to "concat.txt" in: "%CD%"
) else echo INFO: No file matching "*%FileExtension%" found in: "%CD%"
popd
endlocal
前两个命令行完全定义了所需的执行环境,接下来输出一个空行。
然后验证是否使用至少两个非空参数字符串调用批处理文件。
下一行将当前目录的路径压入堆栈,并将当前目录更改为第一个参数指定的目录,该目录预计(但未验证)是批处理文件目录的子目录。如果显示使用的目录路径失败,则会输出错误消息。
您的代码错过了将当前目录更改为
scripts2
,分别指定目标文件时没有目录名称scripts2
,因此在当前目录中创建,无论启动时的当前目录是什么cmd.exe
来处理批处理文件。
接下来,第二个参数被分配给名为
FileExtension
的环境变量,如果第一个字符不是点,则该变量将在开头重新定义为点。
目标文件将被删除,并抑制目标文件
concat.txt
根本不存在的用例的所有错误消息。如果输入的文件扩展名是 .txt
并且目录已包含先前执行的批处理文件中的 concat.txt
,则这是必需的。
最后一个 IF 条件检查是否存在与通配符模式匹配的任何文件(或目录),并将它们一起复制到目标文件
concat.txt
并输出一条小信息消息,或者在没有目录条目与通配符匹配时输出一条不同的信息消息图案。
初始当前目录的路径从堆栈中弹出,并根据代码的预期再次设置为当前目录,然后最终恢复初始执行环境。
另一种解决方案是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
echo(
if "%~1" == "" echo INFO: %~n0 must be called with directory name as first parameter.& exit /B
if "%~2" == "" echo INFO: %~n0 must be called with file extension as second parameter.& exit /B
pushd "%~dp0%~1" 2>nul || (echo ERROR: Directory not found: "%~dp0%~1"& exit /B)
set "FileCount="
set "FileExtension=%~2"
if not "%FileExtension:~0,1%" == "." set "FileExtension=.%FileExtension%"
for /F "eol=| delims=" %%I in ('dir "*%FileExtension%" /A-D /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V /X /C:"concat.txt"') do (
if not defined FileCount ( copy /B /Y "%%I" "concat.txt" >nul ) else copy /B /Y "concat.txt"+"%%I" "concat.txt" >nul
set /A FileCount+=1
)
if not defined FileCount (
echo INFO: No file matching "*%FileExtension%" found in: "%CD%"
goto Finish
)
if %FileCount% == 1 (
echo INFO: Copied one file to "concat.txt" in: "%CD%"
) else (
echo INFO: Copied %FileCount% files to "concat.txt" in: "%CD%"
)
:Finish
popd
endlocal
第二个解决方案比第一个解决方案慢,但可以更好地控制连接在一起的文件的顺序,并且最终信息更好一些。
请注意,这两种解决方案既不是 100% 故障安全,也不是 100% 安全。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
call /?
...解释如何引用批处理文件参数。copy /?
del /?
dir /?
echo /?
endlocal /?
exit /?
findstr /?
for /?
goto /?
if /?
popd /?
pushd /?
set /?
setlocal /?
另请参阅:
>nul
和 2>nul
以及重定向运算符 |
的说明。重定向运算符 >
和 |
必须在 FOR命令行上使用脱字符号
^
进行转义,以便在 Windows 命令解释器在执行执行嵌入 的命令 FOR 之前处理此命令行时将其解释为文字字符dir
和 findstr
命令行,使用在后台启动的单独命令进程。&
和 ||
的说明。因为您从未进入
scripts2
目录,所以 concat.txt
会在您调用脚本时所在的位置创建(很可能是 scripts
)。
@echo off
echo extension
set /p ext=
echo directory
set /p paf=
if not exist "*%paf:"=%" goto no
for /r "%paf:"=%" %%i in (*%ext:"=%) do (
type %%i >>output.txt
)
goto :eof
:no
echo files do not exist
pause
这就是我的做法,如果您想直接从提示符运行它,您只需替换变量并删除输入语句即可