简体   繁体   中英

Batch file to copy contents from sub-folder to parent only if there's one file and it's the same name without extension

I've been fiddling with this for several hours now and I've gotten it almost there but I'm still lacking bits here... I do NOT have access to powershell.exe; I can only use Windows cmd.exe here.

Basically, what I want to do is traverse only the top level folders in the current director and if:

  1. There's only one file in that subfolder and
  2. The file name without the extension matches the name of the folder it is in

If both of those conditions are true, then copy the file one level up and move on to the next folder in the target directory.

Here's what I have so far.

for /D %%f in (*) do (
    set %count&=(dir /b /a-d | find /v /c "?")
    echo %count%
    if %count%=="1" (
        if %~nf=="Something"(
            echo %%f
            echo copy * .. /-Y  
        )
     )
)

Could someone help me fill in the missing bits here?

So far, the value of count is always 0 and I haven't gotten the part that compares the filename to its folder (the current folder in the iteration)

@ECHO OFF
SETLOCAL

for /D %%e in (*) do (
 rem directory name in %%e
 for /f %%c in ('dir /b /a-d "%cd%\%%e" 2^>nul ^| find /v /c ""') do (
  echo filecount IN "%cd%\%%e" is %%c
  if "%%c"=="1" if EXIST "%cd%\%%e\%%~ne.*" (
   echo found "%cd%\%%e\%%~ne.*"
   echo copy "%cd%\%%e\*" "%cd%\" /-Y  
  )
 )
)

GOTO :EOF

Prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) ADFNPSTXZ are also metavariable-modifiers which can lead to difficult-to-find bugs (See for/f from the prompt for documentation)

Perform the dir... on the [current directory\subdirectory found] (probably could also be .\%%e ) and suppress error messages if none found (caret ( ^ ) escapes the redirector > to tell cmd that the > belongs to the dir , not the for )

Pipe the dir report to find (escaped redirector again) to /c count those lines that /v do not contain "" nothing. Put the result in %%c .

This means that %%c will be assigned the file count in the subdirectory. %%c , being a metavariable can be used directly. Had it been assigned to count ( set /a count=%%c ) then since count (being a user-variable) is being changed within a code block (parenthesised code) its value is not available unless delayedexpansion has been invoked Stephan's DELAYEDEXPANSION link

A series of if statements acts like an AND of the conditionals, so we need to determine whether %cd%\%%e\%%~ne.* exists and if it does, since we know that there is but the one file, go copy all of the one file to the parent directory.

Note that if %~nf=="Something"( would yield a syntax error as the ( would be included in the string for comparison. There must be a separator (like Space for instance) before the ( .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM