【问题标题】:How do I use a batch script to copy a file without knowing the full path to that file?如何在不知道该文件的完整路径的情况下使用批处理脚本复制文件?
【发布时间】:2020-01-12 21:18:39
【问题描述】:

我想将文件从闪存驱动器E:\ 复制到本地计算机。但是本地机器上的文件夹结构是这样的:

C:\Device\Number\One\xyz_01-01-19\Path\To\Folder
C:\Device\Number\Two\xyz_01-02-19\Path\To\Folder
C:\Device\Number\Three\xyz_01-03-19\Path\To\Folder
C:\Device\Number\Four\xyz_01-04-19\Path\To\Folder

有数百个设备文件夹,如OneTwo 等,每个文件夹对设备都是唯一的,但所有子文件夹对每个单元都遵循相同的命名约定。 xyz_ 是文件夹名称的固定开头部分,日期格式为 mm-dd-yy 附加在文件夹名称中。

没有规则可以通过批处理脚本自动选择设备文件夹,文件应复制到该设备文件夹中,该文件夹在用户选择的设备文件夹的可变日期相关子文件夹内具有已知路径的子文件夹。因此批处理文件的用户必须输入设备文件夹名称。该文件应仅复制到用户确定的设备文件夹之一。

我遇到的问题是文件夹路径中的日期与一个设备文件夹到下一个设备文件夹不同。除日期外,其他一切都完全相同,我不知道如何获取文件夹名称中包含日期的文件夹名称。

我的脚本类似如下:

REM Asking for the "Device" number
set /P device="Device Number?"
REM Copying files to the server
copy E:\log.pdf C:\Device\Number\%device%\xyz_01-01-19\Path\To\Folder

【问题讨论】:

  • 所以您正在尝试解析C:\Device\Number\*\xyz_??-??-??\Path\To\Folder 之类的路径?如果是这样,请使用嵌套的for /D loosp,它允许为每个匹配的文件夹执行一项任务(如本例中的回显):for /D %%J in ("C:\Device\Number\*") do for /D %%I in ("%%~J\xyz_??-??-??") do echo/%%~I\Path\To\Folder;从那里您可以更进一步,例如插入设备文件夹名称的条件,例如if "%%~nxJ" == "%device%" echo Device folder: %%~J...

标签: batch-file


【解决方案1】:

以下批处理文件可用于此任务:

@echo off
if not exist "C:\Device\Number\" goto :EOF
setlocal EnableExtensions DisableDelayedExpansion

cls
echo Device folders in folder: "C:\Device\Number"
echo/
dir "C:\Device\Number\*" /AD /ON /W | %SystemRoot%\System32\findstr.exe /B /L /C:[
echo/

:PromptDevice
set "DeviceFolder="
set /P "DeviceFolder=Please enter device: "

rem Has the user not input any string?
if not defined DeviceFolder goto PromptDevice
rem Remove all double quotes from string value.
set "DeviceFolder=%DeviceFolder:"=%"
rem Has the user input just one or more double quotes?
if not defined DeviceFolder goto PromptDevice
rem If the user has input the device with [ at beginnning and with ] at end
rem as output by command DIR, remove those square brackets from device string.
if "%DeviceFolder:~0,1%" == "[" set "DeviceFolder=%DeviceFolder:~1%"
if not defined DeviceFolder goto PromptDevice
if "%DeviceFolder:~-1%" == "]" set "DeviceFolder=%DeviceFolder:~0,-1%"
if not defined DeviceFolder goto PromptDevice

rem Determine name of subfolder with date in name.
set "TargetFolder="
for /D %%I in ("C:\Device\Number\%DeviceFolder%\xyz_??-??-??") do set "TargetFolder=%%I\Path\To\Folder"

if not defined TargetFolder (
    echo/
    echo Subfolder xyz_??-??-?? not found in: "C:\Device\Number\%DeviceFolder%"
    echo/
    goto PromptDevice
)
if not exist "%TargetFolder%\" (
    echo/
    echo Folder "%TargetFolder%" not found.
    echo/
    goto PromptDevice
)

echo/
echo Copying log.pdf to "%TargetFolder%" ...
copy /Y /B "%~dp0log.pdf" "%TargetFolder%\"
echo/
endlocal
pause

在初步检查文件夹C:\Device\Number 是否存在之后,命令DIR 用于按名称以宽格式输出此文件夹中的所有子文件夹,并使用FINDSTR 过滤掉所有行输出DIR 不以[ 开头,即页眉和页脚行。 DIR 还输出[.][..],用户必须忽略。

然后提示用户输入设备编号文件夹的名称。请参阅How to stop Windows command interpreter from quitting batch file execution on an incorrect user input? 它解释了用于防止 Windows 命令处理器意外退出批处理文件处理的附加 IF 条件的原因,因为语法错误可能会发生在用户输入错误时设备文件夹名称。

批处理文件使用命令 FOR 和选项 /D 如果输入设备文件夹名称的文件夹完全存在并且该设备文件夹包含非隐藏文件夹,则获取带有日期的子文件夹名称完全匹配通配符模式xyz_??-??-??。否则会通知用户输入的设备文件夹中缺少文件夹 xyz_??-??-??,并再次提示用户输入设备文件夹名称,因为用户输入的文件夹名称很可能不是 100% 正确。

再次检查目标文件夹是否真的存在后,通知用户文件复制,并通过批处理脚本复制文件,希望也成功。批处理文件希望文件复制到包含以%~dp0 引用的批处理文件的目录中,该批处理文件始终扩展为以目录分隔符\ 结尾的批处理字符串。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /? ... 解释 %~dp0 ... 参数 0 的驱动器和路径,即完整的批处理文件路径。
  • cls /?
  • copy /?
  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

有关重定向运算符| 的说明,另请参阅有关Using command redirection operators 的Microsoft 文章。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题 + cmets,这是您文件结构的第一部分(和问题部分):

    C:.
    └───Device
        └───Number
            ├───Four
            │   ├───xyz_1-1-19
            │   ├───xyz_1-2-19
            │   ├───xyz_1-3-19
            │   └───xyz_x-x-xx
            ├───One
            │   ├───xyz_1-1-19
            │   ├───xyz_1-2-19
            │   ├───xyz_1-3-19
            │   └───xyz_x-x-xx
            ├───Three
            │   ├───xyz_1-1-19
            │   ├───xyz_1-2-19
            │   ├───xyz_1-3-19
            │   └───xyz_x-x-xx
            └───Two
                ├───xyz_1-1-19
                ├───xyz_1-2-19
                ├───xyz_1-3-19
                └───xyz_x-x-xx
    

    除非您始终知道选择使用哪个xyz_x-x-xx 文件夹所需的标准,否则您必须依靠人工为您做出决定。在这种情况下,您需要将用户输入添加到您的脚本中。以下是您应该如何处理这个问题(在伪代码中):

    n = 0
    for every directory in "C:\Device\Number\%device%\" {
        n++
        folder[n]=path_to_folder
        echo n) directory_name
    }
    echo Choice:
    choice = user_input
    
    copy E:\log.pdf C:\Device\Number\%device%\folder[choice]\Path\To\Folder
    

    以下是一些帮助您入门的阅读材料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-10
      相关资源
      最近更新 更多