批处理文件到一个文件夹中复制从特定的子文件夹中的文件到目标文件夹(Batch file to cop

2019-10-16 13:27发布

我有一个文件夹结构喜欢他

folder1-------|
              |123456------123.txt
                          abc.txt
              |234567------fgt.txt
                           234.txt
              |abc---------ytr.txt
                           1234.txt

我需要从主文件夹中的子目录的文件复制如果子文件夹中有6个(仅数字)的长度。 所以从123456,234567 .txt文件将被复制和ABC将不会被复制。

我曾尝试使用通配符,但没有成功呢。 提前致谢。

>xcopy /s "C:\Users\xxx.xxx\Desktop\folder1\*\*.txt" "C:\Users\xxx.xxx\Documents\New folder" /l /D:09-09-2019

Answer 1:

好了,下面是一个例子:

@echo off
setlocal enabledelayedexpansion

for /f %%i in ('dir "C:\Users\xxx.xxx\Desktop\folder1\" /b /ad') do (
  set "str=#%%i"
  set "len=0"
  for %%a in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if "!str:~%%a,1!" neq "" (
       set /a "len+=%%a"
       set "str=!str:~%%a!"
       if !len! equ 6 if 1%%i equ +1%%i echo %%i is !len! characters   
     )
   )
)

这会是一个dir ,你给它的路径内的目录。 然后它将测试字符串的长度,如果该长度为6个字符,它将然后测试如果字符串是数字,如果为真,则echo字符串(文件夹名)和它的长度。 然后,您应该测试它是,如果它给你所需要的输出,你可以取代echo与复制串部分。

因此,最终的解决方案将是这样的:

@echo off
setlocal enabledelayedexpansion
set /p "mydate=Enter Date (format dd-mm-yyyy): "
for /f %%i in ('dir "C:\Users\xxx.xxx\Desktop\folder1\" /b /ad') do (
  set "str=#%%i"
  set "len=0"
  for %%a in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if "!str:~%%a,1!" neq "" (
       set /a "len+=%%a"
       set "str=!str:~%%a!"
       if !len! equ 6 if 1%%i equ +1%%i xcopy "C:\Users\xxx.xxx\Desktop\folder1\%%i\*.txt" "C:\Users\xxx.xxx\Documents\New folder" /D:!mydate! 
     )
   )
)


Answer 2:

你可以使用FindStr隔离符合模式的目录:

批处理文件 :

@Echo Off
Set "SrcDir=%UserProfile%\Desktop\folder1"
Set "DstDir=%UserProfile%\Desktop\New folder"
For /F Delims^=^ EOL^= %%A In ('
    "Dir /B/AD "%SrcDir%\*" 2>NUL|FindStr "^[0-9][0-9][0-9][0-9][0-9][0-9]$""
')Do XCopy "%SrcDir%\%%A\*.txt" "%DstDir%\" /D:09-09-2019 /Y>NUL 2>&1

只需修改之间的路径="上线23 ,以满足您的实际源和目标目录。



Answer 3:

这里是尚未实现你想要的(见所有解释另一种方法rem备注):

@echo off
rem // Use a `for /D` loop to iterate through all immediate sub-directories in the given root directory:
for /D %%I in ("%UserProfile%\Desktop\folder1\*") do (
    rem // Store path and name of currently iterated directory in variables:
    set "DIRECTORY=%%~I" & set "NAME=%%~nxI"
    rem // Toggle delayed expansion to be able to write and to read a variable within the same block of code:
    setlocal EnableDelayedExpansion
    rem // Check if directory name holds more than 5 characters:
    if not "!NAME:~5!" == "" (
        rem // Check if directory name holds not more than 6 characters:
        if "!NAME:~0,6!" == "!NAME!" (
            rem // The directory name is exactly 6 characters long.
            rem // Check whether the directory name consists of decimal figures by (mis-)using a `for /F` loop:
            set "FLAG=" & for /F "tokens=1 delims=0123456789 eol=0" %%J in ("!NAME!") do set "FLAG=#"
            rem // The flag variable has not been set, hence the directory name consists of decimal figures:
            if not defined FLAG (
                rem // Do the actual copy job at this point:
                xcopy /I /Y /D:09-09-2019 "!DIRECTORY!\*.txt" "!UserProfile!\Documents\New Folder"
            )
        )
    )
    endlocal
)

您正在尝试使用通配符不仅在一个路径,这不能做(在Windows)的最后一个元素,但你可以使用一个for /D循环来解决通配符上目录层次,如脚本证明。

该脚本使用~ -modifiers (这是相同for像元变量%%I和喜欢争论参考%1 )获取当前迭代目录的纯名称: %%~nxI

要确定的目录名是否是正好六个(6)字符长, 子串扩展被施加。

要确定的目录名是否由十进制数字只,一个for /F回路采用的是(误): for /F在给定的分隔符(选项字符串分割成几部分delims ); 因为所有的十进制数字被定义为分隔符,一个命名的目录1a2b3c将被分成各部分abca成为分配给%%J然后由于tokens=1 ,成为驳回其他部分),但目录名123456留下,因为这是一个唯一的分隔符字符串,在这种情况下,没有for /F循环不重复的。 加上标志样可变FLAG变成在体内设置for /F循环,我们能够确定环路是否迭代,从而知道当前目录的名称是否只包含十进制数字。

脚本写入和从可变读取NAME在相同的代码块,这通常不能被完成,除非启用延迟变量扩展 。

您可以使用系统环境变量%UserProfile%而不是指定C:\Users\xxx.xxx ,所以脚本甚至可以在系统上工作,在用户配置文件目录不在默认位置。



文章来源: Batch file to copy file from specific sub folder inside a folder to destination folder