2

Situation:

Numerous sub-folders with random folder names containing several files with random names. Some I want to retain, others can be deleted.

Goal:

Move the files with extensions: *.exe *.pdf *.avi or other specified extentions out of the subfolders and into a common separate folder without recreating the previous folder structure. So that I have one folder with just the files I want, leaving behind any other file types. Then log the subfolder directory names (results-log.log) and delete the subfolders and everything left in them.

Example; starting:

  • parent1
    • sub1
      • random1.exe
      • random2.pdf
      • random3.txt
    • sub2
      • random4.exe
      • random5.avi
      • random6.log
      • random7.jpg

End result:

  • parent2
    • results-log.log
    • random1.exe
    • random2.pdf
    • random4.exe
    • random5.avi

So I've searched around for other answers and it looks like I need some sort of FOR loop, but I don't understand enough of how that works with parameters to do what I need. Moving pdf files to parent folder from subfolder with variable names is one example I looked at, and I looked over the suggested reading, but I totally don't get how the parameters and variables work. Especially where I need to cover several file types.

So far I'm looking at something like this:

@ECHO OFF
SETLOCAL EnableExtensions
set "_parent=c:\logs\cache\"
set "_dest=c:\archive\"
for /D /r %%G in ("%_parent%\*") do (
  if exist "%%~G\*.pdf" (
    echo move /B "%%~G\*.pdf" "%_dest%\"
  ) else (
    echo nothing to copy "%%~G\*.pdf" "%_parent%\"
  )
)
  • Line 3 I believe that sets "c:\logs\cache\" as the parent folder, so in my example about that would equal "parent1"
  • Line 4 should set the destination for example folder "parent2" as "c:\archive"
  • Line 5 is %%G correct? Does it matter what the letter is?
  • Line 6 how do I specify the other file extensions I want to look for?
  • Line 7 do I want to use move or something else, and what's the /B parameter? /y is the only one I know of for move.

Hopefully that's enough info, can edit as needed for more info.

0

1 Answer 1

3

All you need to do is make multiple if statements I would think. So inside your loop it would look like this:

IF exist "%%G\*.pdf" (
    move /Y "%%G\*.pdf" "%_dest%\"
    echo %%G>>"%_dest%\results-log.log
)

IF exist "%%G\*.exe" (
    move /Y "%%G\*.exe" "%_dest%\"
    echo %%G>>"%_dest%\results-log.log
)
IF exist "%%G\*.avi" (
    move /Y "%%G\*.avi" "%_dest%\"
    echo %%G>>"%_dest%\results-log.log
)

If you want to keep the message saying nothing to move, you can always set some variable if it gets inside one of those IF statements and check that it's set.

I'm not sure what /B is, that doesn't look right to me. I think you're right with /y.

The G can be any character, but it can't be more than one character. G is what is generally used.

I would suggest looking into powershell scripts for things like this. In my opinion it's cleaner and more simple to do things like this with less lines of code. There might be a command to move all files with multiple extensions at once, but from what I understand that syntax isn't usually available for move in most versions of DOS.

EDIT:

I've tested this locally and it seems to work for what you are doing. You'll need to tweak it for your specific case.

@ECHO OFF
SETLOCAL EnableExtensions enabledelayedexpansion
set _parent=c:\logs\cache\
set _dest=c:\archive\
set found=0

for /R  %_parent% %%G in (.) do (
    set found=0
    IF exist "%%G\*.pdf" (
        move /Y "%%G\*.pdf" "%_dest%\"
        set found=1
    )
    IF exist "%%G\*.exe" (
        move /Y "%%G\*.exe" "%_dest%\"
        set found=1
    )
    IF exist "%%G\*.avi" (
        move /Y "%%G\*.avi" "%_dest%\"
        set found=1
    )

    IF !found!==1 (
        rd /s /q "%%G"
        echo %%G>>"%_dest%\results-log.log"
    )
)

endlocal

Using the /D option in the for loop attaches the current directory where you're running the script to the %%G variable which I don't think is what you want. The way I've written it above basically says recurse all folders in the parent directory and set %%G to that location (.).

You have to add the enabledelayedexpansion as well so that you can use the found variable in different blocks, then you have to call !found! instead of %found% to use it. Just a weird quirk of batch scripting.

If all this syntax seems really weird to you, you're not alone. You just have to research away and just do your own testing to see what happens until you get it to do what you want. Hopefully when you jump into powershell you'll find debugging using powershell ISE and the syntax used much more simple.

12
  • I haven't tested all of this syntax, but it should at least get you close to what you need. I would put all the conditions in one if statement, but I think you can only do and and not or for if conditions. One more reason to use powershell :)
    – mrfreester
    Commented Oct 19, 2015 at 22:18
  • Okay, so to make sure I'm understanding this correctly. Your code replaces my IF statement, but I still keep the first 4 lines as they are, correct? Then what do I do about the else portion? Add it after all of my IF statements with an echo to the log file? p.s. I'm open to doing this with PowerShell instead, but I know even less about using PS, it's on my list of things I need to learn soon.
    – WraythOsu
    Commented Oct 20, 2015 at 15:07
  • I added the entire example of using a variable to see if anything was moved. You'll use that instead of an else statement since batch doesn't support else if's
    – mrfreester
    Commented Oct 20, 2015 at 17:18
  • It's working!!! (imagine young Anakin in eps 1) :-) So, last bit is to delete the old subfolders after we move the files. so do I add rd /s /q %%G between the move line and the set line in each statement? My only concern here is that I don't want to delete a folder that might contain a file type I haven't factored in the script. So say a folder shows up as a .msi instead of .exe, I want that folder to be left alone for now. So I only want it to delete a folder if a file has been moved out.
    – WraythOsu
    Commented Oct 20, 2015 at 19:50
  • I would probably put the rd /q %%G line the last if block where you write to the log file since you should get into that only if you deleted something in the previous if blocks. I would probably leave out the /s option as I think that will delete the directory even if there are still files in it. If you leave out /s then I'm pretty sure it'll do what you want, which is delete the folder only if it's empty.
    – mrfreester
    Commented Oct 20, 2015 at 22:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .