Batch file to copy file from specific sub folder inside a folder to destination folder

我的梦境 提交于 2020-01-15 10:15:19

问题


I have a folder structure like his

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

I need to copy files from Main folders sub directories if the sub folder has a length of 6(only numbers) . So .txt files from 123456,234567 will be copied and abc will not be copied.

I have tried using wildcards but not succeed yet. Thanks in advance.

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


回答1:


Ok, so here is an example:

@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   
     )
   )
)

This will do a dir of the directories inside the path you give it. It will then test the length of the string, if the length is 6 characters, it will then test if the string is numeric, if true, it will echo the string (folder name) and the length of it. You should then test it as is and if it gives you the required output, you can replace echo portion with your copy string.

So your final solution will be something like:

@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! 
     )
   )
)



回答2:


You could use FindStr to isolate the directories matching your pattern:

batch-file:

@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

Just modify the paths between the = and " on lines 2 and 3 to suit your actual source and destination directories.




回答3:


Here is yet another method to achieve what you want (see all the explanatory rem remarks):

@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
)

You were trying to use wildcards not only in the last element of a path, which cannot be done (in Windows), but you can use a for /D loop to resolve the wildcards in upper directory levels, as demonstrated in the script.

The script uses ~-modifiers (which are the same for for meta-variables like %%I and for argument references like %1) to get the pure name of the currently iterated directory: %%~nxI.

To determine whether or not the directory name is exactly six (6) characters long, sub-string expansion is applied.

To determine whether or not the directory name consists of decimal digits only, a for /F loop is (mis-)used: for /F splits strings into parts at given delimiter characters (option delims); since all decimal digits are defined as delimiters, a directory named 1a2b3c would be split into the parts a, b and c (a becomes assigned to %%J then due to tokens=1, the other parts become dismissed), but a directory name 123456 leaves nothing behind since this is a delimiter-only string, in which case the for /F loop does not iterate at all. Together with a flag-like variable FLAG that becomes set in the body of the for /F loop we are able to determine whether or not the loop iterated, thus knowing whether the current directory name only consists of decimal digits.

The script writes to and reads from the variable NAME in the same block of code, which can normally not be done, unless you enable delayed variable expansion.

You can use the system environment variable %UserProfile% instead of specifying C:\Users\xxx.xxx, so the script may even work on a system where the user profile directory is not at the default location.



来源:https://stackoverflow.com/questions/57865073/batch-file-to-copy-file-from-specific-sub-folder-inside-a-folder-to-destination

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!