0

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)

Compo
  • 36,585
  • 5
  • 27
  • 39

1 Answers1

0
@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 (.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Whoa. I was woefully underqualified to try to do this on my own. Your answer and explanations are amazing. I'll give this a spin and see how many ways I can break my computer. If I'm really really luck, I can unbreak it with this. Thank you. If it works, I'll tag it. If it doesn't, I'll ask questions. Thanks again! – MetalGlitch Dec 07 '22 at 21:30
  • I just tested it. Seems to work once the copy command is changed to `copy "%cd%\%%e\*" "%cd%\" /-Y` Once again, you rock. Thank you! – MetalGlitch Dec 07 '22 at 23:01