1

I want to move up all files one level recursively.

The current folder structure is given bellow

D:\_Courses>tree /a
D:.
+---Course 1
|   \---Download
+---Course 2
|   \---Download
+---Course 3
|   \---Download
\---Course 4
    \---Download

I want to move all files from "Download" folder to its parent folder.

It means,

All files from "Course 1/Download" should go to "Course 1"

All files from "Course 2/Download" should go to "Course 2"

All files from "Course 3/Download" should go to "Course 3"

All files from "Course 4/Download" should go to "Course 4"

Problem 1 : Showing a folder that does not exist

When I used the following command

D:\_Courses>FOR /R /D %I IN (Download\) DO @ECHO %I

The output is given bellow

D:\_Courses\Download\
D:\_Courses\Course 1\Download\
D:\_Courses\Course 1\Download\Download\
D:\_Courses\Course 2\Download\
D:\_Courses\Course 2\Download\Download\
D:\_Courses\Course 3\Download\
D:\_Courses\Course 3\Download\Download\
D:\_Courses\Course 4\Download\
D:\_Courses\Course 4\Download\Download\

However, There are no folder called

D:\_Courses\Course 1\Download\Download

Problem 2 : Moving to wrong directory

When I gave the following command

D:\_Courses>FOR /R /D %I IN (Download\) DO move "%I"*.* ..

All the files from all 4 download folders moved to D:

The output was -

D:\_Courses>move "D:\_Courses\Download\"*.* ..
The system cannot find the file specified.

D:\_Courses>move "D:\_Courses\Course 1\Download\"*.* ..
D:\_Courses\Course 1\Download\518057_00_01.mp4
D:\_Courses\Course 1\Download\518057_00_02.mp4
D:\_Courses\Course 1\Download\518057_00_03.mp4
...
       28 file(s) moved.

D:\_Courses>move "D:\_Courses\Course 1\Download\Download\"*.* ..
The system cannot find the file specified.

D:\_Courses>move "D:\_Courses\Course 2\Download\"*.* ..
D:\_Courses\Course 2\Download\486757_00_01.mp4
D:\_Courses\Course 2\Download\486757_00_02.mp4
D:\_Courses\Course 2\Download\486757_00_03.mp4
D:\_Courses\Course 2\Download\486757_00_04.mp4
...
       40 file(s) moved.

D:\_Courses>move "D:\_Courses\Course 2\Download\Download\"*.* ..
The system cannot find the file specified.

D:\_Courses>move "D:\_Courses\Course 3\Download\"*.* ..
D:\_Courses\Course 3\Download\569336_00_01.mp4
D:\_Courses\Course 3\Download\569336_00_02.mp4
D:\_Courses\Course 3\Download\569336_00_03.mp4
D:\_Courses\Course 3\Download\569336_01_01.mp4
D:\_Courses\Course 3\Download\569336_01_02.mp4
...
       19 file(s) moved.

D:\_Courses>move "D:\_Courses\Course 3\Download\Download\"*.* ..
The system cannot find the file specified.

D:\_Courses>move "D:\_Courses\Course 4\Download\"*.* ..
D:\_Courses\Course 4\Download\518056_00_01.mp4
D:\_Courses\Course 4\Download\518056_00_02.mp4
D:\_Courses\Course 4\Download\518056_00_03.mp4
...
       17 file(s) moved.

D:\_Courses>move "D:\_Courses\Course 4\Download\Download\"*.* ..
The system cannot find the file specified.
Ahmad Ismail
  • 11,636
  • 6
  • 52
  • 87
  • So you want to move all files in all subdirectories to the root directory? or only from a given path? – Gerhard Feb 02 '18 at 08:41
  • @GerhardBarnard this is just the pattern of the folder structure. If a folder named Download exists I want to move it up one level. I am working on it. The following command FOR /R /D %I IN (Download\) DO move "%I"*.* "%I"\.. seems to work. Can you please check and confirm it. Thanks – Ahmad Ismail Feb 02 '18 at 08:44
  • ah ok, now I get what you want. Ignore the previous comment – Gerhard Feb 02 '18 at 08:47
  • FOR /R /D %I IN (Download) DO move "%I"\*.* "%I"\.. – Ahmad Ismail Feb 02 '18 at 08:48
  • 1
    What will happen if there are files with identical names? – lit Feb 02 '18 at 15:38

3 Answers3

1

Ok, this should do what you want.

@echo off
for /r /d %%a in (Download) do (
echo move "%%a\*" "%%a\.."
)

Remove echo only once you are happy the results looks fine when echo'd.

Be carefull where you place the batchfile as it will recursively search for all directories named Download from the root of the batch file. Also ensure that the batch file does not exist in a directory named Download

EDIT: to run from cmdline instead of batch (Ensure you copy the code exactly):

for /r /d %a in (Download) do (echo move "%a\*" "%a\..")
Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • for /r /d %a in (Download) do move "%a\*.*" "%a\.." The command works fine but the problem is "D:\_Courses>move "D:\_Courses\Course 4\Download\Download\*.*" "D:\_Courses\Course 4\Download\Download\.." The system cannot find the file specified." I do not have any folder named "D:\_Courses\Course 4\Download\Download" in my directory structure. What it the problem. – Ahmad Ismail Feb 02 '18 at 09:04
  • 1
    @blueray yes, if from cmdline, but add %%a if from batch file – Gerhard Feb 02 '18 at 09:06
  • keep in mind you have a `batch-file` tag, hence a `batch-file` answer :) – Gerhard Feb 02 '18 at 09:07
  • @blueray, in your comment above you used, `move "%a` instead of `move "%a\ `! – Compo Feb 02 '18 at 10:53
  • @blueray Did you copy my code exactly? Please copy exactly and create a batch file, else if you want to run from cmdline instead, see my edit at the bottom of my answer. – Gerhard Feb 02 '18 at 10:57
  • @Gerhard, will using `"%a\.*"` not mean that only items beginning with **`.`** will be moved? – Compo Feb 02 '18 at 11:31
  • @compo thanks, missed a `*` but made it `\*` which is better written – Gerhard Feb 02 '18 at 11:41
0

Copied from this answer:

You may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:

@echo off
call :treeProcess
goto :eof

:treeProcess
rem Do whatever you want here over the files of this subdir, for example:
move *.* ..
for /D %%d in (*) do (
    cd "%%d"
    call :treeProcess
    cd ..
)
exit /b
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Just a heads up; I have a sneaky suspicion, _despite the batch-file tag_, that they are running this directly from a cmd.exe window. – Compo Feb 02 '18 at 17:19
0

This PowerShell script makes use of the directory and file object Parent property to copy the files. When you are confident that the correct files will be copied to the correct destination, remove the WhatIf from the Move-Item cmdlet.

Get-ChildItem -Directory -Path C:/src/t/_Courses -Recurse -Filter 'Download' |
    ForEach-Object {
        $newdir = $_.Parent.FullName
        Get-ChildItem -File -Path $_.FullName |
            ForEach-Object { Move-Item -LiteralPath $_.FullName $newdir -WhatIf }
    }

To use this from a cmd shell, put the code above into a file such as movedowns.ps1, then run it.

powershell -NoProfile -File movedowns.ps1
lit
  • 14,456
  • 10
  • 65
  • 119