0

这是一个非常基本的批处理脚本。这是我处理这个话题的第一天。

我想创建一个以目录名和扩展名作为参数的脚本,如果该目录存在,则具有该扩展名的每个文件的内容将被写入另一个文件。

例子:

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

我究竟做错了什么?

4

3 回答 3

1

文件内容复制任务可以通过以下方式完成:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
echo/
if "%~1" == "" echo INFO: %~n0 must be called with directory name as first parameter.& goto :EOF
if "%~2" == "" echo INFO: %~n0 must be called with file extension as second parameter.& goto :EOF
pushd "%~dp0%~1" 2>nul || (echo ERROR: Directory not found: "%~dp0%~1"& goto :EOF)
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根本不存在的用例,目标文件被删除,同时抑制所有错误消息。如果输入的文件扩展名为 is.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.& goto :EOF
if "%~2" == "" echo INFO: %~n0 must be called with file extension as second parameter.& goto :EOF
pushd "%~dp0%~1" 2>nul || (echo ERROR: Directory not found: "%~dp0%~1"& goto :EOF)

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 /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?

也可以看看:

于 2021-05-23T22:06:50.467 回答
0
@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

我就是这样做的,如果你想直接从提示符运行它,你可以替换变量并删除输入语句

于 2021-05-24T10:22:21.313 回答
0

因为您从不进入scripts2目录,concat.txt所以会在您调用脚本时所在的同一位置创建(很可能scripts)。

于 2021-05-23T17:32:41.613 回答