根据子文件夹名称

时间:2016-05-16 03:38:45

标签: batch-file cmd

我是批处理脚本的新手,我需要帮助来解决这个重复的手动任务。我需要自动使用批处理文件

我有这个目录结构如下例

c:\machines\models\a\defects
c:\machines\models\b\defects
c:\machines\models\c\defects
c:\machines\models\d\defects
and it continues e, f, g, h

(a,b,c,d只是示例,因为机器将根据我们测试的模型生成文件夹)

我想移动缺陷文件夹内容(包括其中的子文件夹和文件) 到具有以下内容的目标文件夹: 1.当前日期 2.使用批处理文件(ms dos)

,根据其模型重命名缺陷文件夹,如下面所需的输出所示
e:\backup\currentdate\a_defects
e:\backup\currentdate\b_defects
e:\backup\currentdate\c_defects
e:\backup\currentdate\d_defects

请帮助!

2 个答案:

答案 0 :(得分:1)

以下是此任务的注释批处理代码:

@echo off
setlocal

rem Define source and backup path.
set "SourcePath=C:\machines\models"
set "BackupPath=E:\backup"

rem Get current date in format YYYY-MM-DD independent on local date format.
for /F "skip=1 tokens=1 delims=." %%T in ('%SystemRoot%\System32\wbem\wmic.exe OS get localdatetime') do set LocalDateTime=%%T & goto ReformatDate
:ReformatDate
set "YearMonthDay=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%

rem For each subfolder in source path check if there is a subfolder "defects".
rem If subfolder "defects" exists, copy all files and subfolders of "defects"
rem to the appropriate backup directory with current date and subfolder name
rem in source folder path. Then remove the subfolder "defects" in source
rem folder even if being completely empty to avoid processing this folder
rem again when not being recreated again in the meantime.

for /D %%# in ("%SourcePath%\*") do (
    if exist "%%#\defects\*" (
        %SystemRoot%\System32\xcopy.exe "%%#\defects\*" "%BackupPath%\%YearMonthDay%\%%~nx#_defects\" /H /I /K /Q /R /S /Y >nul
        rd /Q /S "%%#\defects"
    )
)
endlocal

在命令提示符窗口wmic OS get localdatetime中运行一次以查看此命令输出的内容,以更好地了解如何以YYYY-MM-DD格式确定当前日期。使用%DATE%会更快,但%DATE%的日期字符串格式取决于Windows区域和语言设置中设置的国家/地区,因此需要了解运行此批处理文件的计算机上的日期字符串格式。

如果defects目录中有models子文件夹,但在整个{{1}中,带有使用选项的命令 XCOPY 不会在备份目录中创建子文件夹子文件夹树至少有1个要复制的文件。

使用环境变量 DATE 的替代代码,期望扩展日期字符串以:defects结尾,例如MM/DD/YYYY,在答案中详细解释:
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?

Tue 05/17/2016

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

  • @echo off setlocal rem Define source and backup path. set "SourcePath=C:\machines\models" set "BackupPath=E:\backup" rem Get current date in format YYYY-MM-DD depending on local date format. set "YearMonthDay=%DATE:~-4,4%-%DATE:~-10,2%-%DATE:~-7,2%" rem For each subfolder in source path check if there is a subfolder "defects". rem If subfolder "defects" exists, copy all files and subfolders of "defects" rem to the appropriate backup directory with current date and subfolder name rem in source folder path. Then remove the subfolder "defects" in source rem folder even if being completely empty to avoid processing this folder rem again when not being recreated again in the meantime. for /D %%# in ("%SourcePath%\*") do ( if exist "%%#\defects\*" ( %SystemRoot%\System32\xcopy.exe "%%#\defects\*" "%BackupPath%\%YearMonthDay%\%%~nx#_defects\" /H /I /K /Q /R /S /Y >nul rd /Q /S "%%#\defects" ) ) endlocal
  • echo /?
  • endlocal /? ...还解释了for /?(模型子文件夹的名称(和扩展名))。
  • %%~nx#
  • if /?
  • rd /?
  • set /?
  • setlocal /?
  • wmic.exe OS get /?

另请参阅有关Using command redirection operators的Microsoft文章,以了解xcopy /?的含义。

为什么>nul而不仅仅%%~nx#作为文件夹没有文件扩展名

Windows命令处理器不确定字符串是文件夹还是文件名。最后反斜杠后的所有内容都被解释为文件名,与实际文件或文件夹的名称无关。并且字符串中最后一个反斜杠之后的最后一个点之后的所有内容都被解释为文件扩展名,即使这意味着由%%~n#引用的文件夹或文件名是空字符串,因为文件夹/文件名已启动有一个点并且不包含一个像* nix系统上的许多“隐藏”文件那样的点,例如%~n。因此,如果在命令行上需要文件夹或文件的整个名称,则应始终使用.htaccess

答案 1 :(得分:0)

这是我的注释代码。 Mofi更快(没有老人站点......)

使用robocopy command而不是deprecated xcopy

注意/L切换robocopy命令:仅限列表 - 不要复制,添加时间戳或删除任何文件。在调试之前删除/L开关。

@ECHO OFF
SETLOCAL EnableExtensions
rem obtain %_currentdate% variable in locale independent yyyymmdd format
for /f "tokens=2 delims==" %%G in (
  'wmic OS get localdatetime /value^|find "="') do set "_currentdate=%%G"
set "_currentdate=%_currentdate:~0,8%"
rem show %_currentdate% variable for debugging purposes
set _currentdate

rem appoint source and target directories
set "_sourcedir=c:\machines\models"
set "_targetdir=E:\backup\%_currentdate%"

for /F "delims=" %%G in ('dir /B /AD "%_sourcedir%\"') do (
  set "_notEmpty="
  rem check if `defects` folder exists 
  if exist "%_sourcedir%\%%G\defects\*" (
    rem credit and tribute to DBenham in https://stackoverflow.com/a/10818854/3439404
    rem check if a folder contains at least one file 
    >nul 2>nul dir /a-d "%_sourcedir%\%%G\defects\*" && (set "_notEmpty=f")
    rem check if a folder or any of its descendents contain at least one file
    >nul 2>nul dir /a-d /s "%_sourcedir%\%%G\defects\*" && (set "_notEmpty=f")

    if defined _notEmpty (
        rem create target directory silently; suppress error message 'already exists'
        md "%_targetdir%\%%G_defects\" >NUL 2>&1

        rem move content of %_sourcedir%\%%G\defects\* to %_targetdir%\%%G_defects\
        robocopy "%_sourcedir%\%%G\defects" "%_targetdir%\%%G_defects" /S /E /MOVE /L

        rem recreate source directory deleted (moved) by robocopy 
        md "%_sourcedir%\%%G\defects\" >NUL 2>&1
    ) else (
        echo nothing to do in %_sourcedir%\%%G\defects
    )
  ) else (
      echo nothing to do in %_sourcedir%\%%G
  )
)

this answer中向DBenham表示感谢并致敬(检查文件夹是否为空)。