Batch copy command doesn't reach subfolder - windows

I have a batch command to copy and move file with a new name to another directory. When I added one more level of subfolder it does not copy but when I remove the added subfolder and move the file to the previous level it does copy. Here is it is:
cd /d dir "U:\Sourcing\Vendor Demand Planning\Customer CPFR\BBM\"
for /f "delims=" %%I in ('dir /b /o:-d "BBM Tool *.xlsx"') do (
copy "%%I" "..\Pricing Project\BBM Tool.xlsx"
exit /b
)
If I removed the BBM level and move the file into the Customer CPFR level it works. I edited this batch from another one that had the target file in the CPFR folder. The file I need to copy is in the BBM folder.

Change COPY to XCOPY and use /S
See XCOPY /?

I'd say that the "Pricing Project" directory is on the same level as "Customer CPFR" hence the target of the copy should be "..\..\Pricing Project...
(later edit)
Also dir in the CD line should be removed.

Related

Moving files from more than one folder to the parent directory using CMD

I have a folder Target contains multiple folders,
each folder contains one file with the same name of the folder
I want to move the files in folders Part1,Part2,Part3,Part4 and Part5
to parent folder ("Target" in this case) using cmd then delete the folders.
The result should be like that :
In Linux i could've used mv Part*\*.* ..
I've tried copy "Part*\*" "" command,
but it doesn't work.
Use a For loop. The key to getting directory names in this code is "dir /a:d" which only lists directories. I put that into the %%a variable. Use %~dp0 to refer to the directory the batch file is in. If your bat is somewhere else, do a find and replace all for that to the directory path you need. Lastly use RMDIR to remove each folder with /q /s to make it silent and remove all files within the directory (part1 part2 etc...) and the directories themselves.
#echo off
for /f "tokens=* delims=" %%a in ('dir /a:d /b "%~dp0"') do (
copy "%~dp0%%a\*.*" "%~dp0"
RMDIR /q /s "%~dp0%%a"
)
In the Windows Command Prompt, copy "Part*\*" "" cannot work, because wildcards are only permitted in the last element of a path but not somewhere in the middle.
To work around this, use a for /D loop to resolve wildcards in Part*, then let copy deal with the remaining ones:
for /D %I in ("Part*") do #copy "%~I\*" ".."
To move the files rather than to copy, simply replace copy by move. If you want to remove empty sub-directories then, append rd using &&:
for /D %I in ("Part*") do #move "%~I\*" ".." && #rd "%~I"
To use the above code fragments in a batch-file, ensure to double all the %-signs.

How to delete a specific sub-folder in a parent folder using a batch file?

I would like to create a batch file deleting or removing the folder C:\temp\root\students\type1, its subfolder and all the files.
The folders and files I do have are as follows:
C:\temp
C:\temp\root
C:\temp\root\students
C:\temp\root\tutors
C:\temp\root\students\type1
C:\temp\root\students\type2
C:\temp\root\tutors\type1
C:\temp\root\tutors\type2
C:\temp\root\students\type1\details.txt
C:\temp\root\students\type1\assignment1
C:\temp\root\students\type1\assignment1\results.txt
The folder C:\temp\root\students\type1\assignment1 is specified in the batch file.
I would like to go one folder/directory up and delete or remove C:\temp\root\students\type1 in my batch file (test.bat).
Please help me with this.
Use this:
rd /s /q C:\temp\root\students\type1
It will remove files and folders recursively, caution, without prompt. It's kind of a substitute for the good old deltree. Best.
EDIT: within your notepad, create your mygoodbatch.bat with this content:
md C:\temp
md C:\temp\root
md C:\temp\root\students
md C:\temp\root\tutors
md C:\temp\root\students\type1
md C:\temp\root\students\type2
md C:\temp\root\tutors\type1
md C:\temp\root\tutors\type2
md C:\temp\root\students\type1\details.txt
md C:\temp\root\students\type1\assignment1
md C:\temp\root\students\type1\assignment1\results.txt
rd /s /q C:\temp\root\students\type1
(md is the make dir dos command, so all the lines beginning with it are creating the folders - the last line is the one to del your level 4AA)
Save this batch on the root of your disk and then run it. I really wish this is what you want. What I yet didn't understand is: you are creating a directory structure and, at the same time, excluding level 4AA... is that it?
You can use a for loop to get the parent folder for a given folder:
set target_dir=C:\temp\root\students\type1.test\assignment1
for %%a in ("%target_dir%") do (
echo Removing %%~dpa%
rd /s/q %%~dpa%
)

How to execute an application existing in each specific folder of a directory tree on a file in same folder?

I have some folders with different names. Each folder has a specific structure as listed below:
Folder1
Contents
x64
Folder1.aaxplugin
TransVST_Fixer.exe
Folder 2
Contents
x64
Folder 2.aaxplugin
TransVST_Fixer.exe
There are two files within each subfolder x64. One file has the same name as the folder two folder levels above. The other file is an .exe file whose name is the same in all folders.
Now I need to run file with file extension aaxplugin on each specific .exe file. It would be obviously very time consuming opening each and every single folder and drag & drop each file on .exe to run it on this file.
That's why I am trying to create a batch script to save some time.
I looked for solutions here on Stack Overflow. The only thing I have found so far was a user saying this: When I perform a drag & drop, the process 'fileprocessor.exe' is executed. When I try to launch this exe, though, CMD returns error ('not recognized or not batch file' stuff).
How can I do this?
UPDATE 12/22/2015
I used first a batch file with following line to copy the executable into x64 subfolder of Folder1.
for /d %%a in ("C:\Users\Davide\Desktop\test\Folder1\*") do ( copy "C:\Program Files\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%a\x64\" 2> nul )
After asking here, I tried the following script:
for /f "delims=" %%F in ('dir /b /s x64\*.aaxplugin') do "%%~dpFTransVST_Fixer.exe" "%%F"
Unfortunately, the output is as following
C:\Users\Davide\Desktop>for /F "delims=" %F in ('dir /b /s x64\*.aaxplugin') do "%~dpFTransVST_Fixer.exe" "%F"
The system cannot find the file specified.
Try the following batch code:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\Desktop\test" %%F in (*.aaxplugin) do (
set "FilePath=%%~dpF"
if not "!FilePath:\x64\=!" == "!FilePath!" "%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%F"
)
endlocal
The command FOR with option/R searches recursive in all directories of directory %USERPROFILE%\Desktop\test being expanded on your machine to C:\Users\Davide\Desktop for files with file extension aaxplugin. The loop variable F contains on each loop run the name of the found file with full path without surrounding double quotes.
The drive and path of each found file is assigned to environment variable FilePath.
Next a case-sensitive string comparison is done between file path with all occurrences of string \x64\ case-insensitive removed with unmodified file path.
Referencing value of environment variable FilePath must be done here using delayed expansion because being defined and evaluated within a block defined with ( ... ). Otherwise command processor would expand %FilePath% already on parsing the entire block resulting in a syntax error on execution because string substitution is not possible as no environment variable FilePath defined above body block of FOR loop.
The strings are not equal if path of file contains a folder with name x64. This means on provided folder structure that the file is in folder x64 and not somewhere else and therefore the application is executed next from its original location to fix the found *.aaxplugin file.
The line with IF is for the folder structure example:
if not "C:\Users\Davide\Desktop\test\Folder1\Contents" == "C:\Users\Davide\Desktop\test\Folder1\Contents\x64\"
if not "C:\Users\Davide\Desktop\test\Folder 2\Contents" == "C:\Users\Davide\Desktop\test\Folder 2\Contents\x64\"
So for both *.aaxplugin files the condition is true because the compared strings are not identical
Also possible would be:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%F in ('dir /A-D /B /S "%USERPROFILE%\test\*.aaxplugin" 2^>nul') do (
set "FilePath=%%~dpF"
if not "!FilePath:\x64\=!" == "!FilePath!" "%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%F"
)
endlocal
But command DIR is not really necessary as it can be seen on first provided code.
But if the application TransVST_Fixer.exe for some unknown reason does its job right only with directory of file being also the current directory, the following batch code could be used instead of first code using the commands pushd and popd:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\test" %%F in (*.aaxplugin) do (
set "FilePath=%%~dpF"
echo !FilePath!
if /I "!FilePath:~-5!" == "\x64\" (
pushd "%%~dpF"
"%ProgramFiles%\Sugar Bytes\TransVST\TransVST_Fixer.exe" "%%~nxF"
popd
)
)
endlocal
There is one more difference in comparison to first code. Now the last 5 characters of path of file are compared case-insensitive with the string \x64\. Therefore the file must be really inside a folder with name x64 or X64. A folder with name x64 or X64 anywhere else in path of file does not result anymore in a true state for the condition as in first two batch codes.
But if for some unknown reason it is really necessary to run the application in same folder as the found *.aaxplugin and the directory of the file must be the current directory, the following batch code could be used:
#echo off
setlocal EnableDelayedExpansion
for /R "%USERPROFILE%\test" %%# in (*.aaxplugin) do (
set "FilePath=%%~dp#"
if /I "!FilePath:~-5!" == "\x64\" (
pushd "%%~dp#"
"%%~dp#TransVST_Fixer.exe" "%%~nx#"
popd
)
)
endlocal
The path of the file referenced with %%~dpF always ends with a backslash which is the reason why there is no backslash left of TransVST_Fixer.exe (although command processor could handle also file with with two backslashes in path).
In batch code above character # is used as loop variable because %%~dp#TransVST_Fixer.exe is easier to read in comparison to %%~dpFTransVST_Fixer.exe. It is more clear for a human with using # as loop variable where the reference to loop variable ends and where name of application begins. For the command processor it would not make a difference if loop variable is # or upper case F.
A lower case f would work here also as loop variable, but is in general problematic as explained on Modify variable within loop of batch script.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
endlocal /?
for /?
if /?
popd /?
pushd /?
set /?
setlocal /?
Your question isn't quite clear, but it seems, something like this should work:
for /f "delims=" %%f in ('dir /b /s X64\*.ext') do "%%~dpfMyExe.exe" "%%f"
Maybe you have to change directory to each folder (depends on your .exe):
for /f "delims=" %%d in ('dir /B /ad') do (
pushd "%%d"
for /f "delims=" %%f in ('dir /b "contents\x64\*.ext"') do (
cd Contents\x64
MyExe.exe "%%f"
)
popd
)
Assuming:
The Directory structure is fixed and the files are indeed in a subfolder contents\X64\.
MyExe.exe is the same (name) in every folder.
There is only one file *.ext in every folder.
I'll give you the script I created for doing so, hope it works for you
for /d %%d IN (./*) do (cd "%%d/Contents/x64" & "../../../TransVST_Fixer.exe" "%%d" & cd "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins")
Please note that I placed the fixer inside the root folder so I just have to copy it once. You have to place it inside your root folder and execute it. What it does:
iterate over each folder
for each one it enters /Contents/x64, executes the fixer (wich is 3 levels above) and after that returns to the original folder.
If you have your plugins in a different folder, you just have to change this part replacing the path for the one you have your plugins in.
cd "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins"
REMEMBER to place the script on that folder. For this example I place my script on the folder "/Program Files (x86)\Common Files\Avid\Audio\Plug-Ins" and run it (as a .bat).
PS: the fixer will place the fixed plugins in "C:\Users\Public\modified" (just read the screen while executing, it gives you the new files path. If you want to move them to the right path, you can execute this from the new files path ("C:\Users\Public\modified")
for %%d IN (*.aaxplugin) do (mkdir "%%d_temp/Contents\x64" & move "%%d" "%%d_temp/Contents\x64/%%d" & rename "%%d_temp" "%%d")
with that, I iterate over every plugin and create a folder with the same name (I create _temp because of name colision, after moving the file I rename it to the correct one), also with the subfolder "/Contents/x64", and move the plugin inside. Once donde, you can just take the resulting folders and place them in their correct path.
Hope it works, for me it works like a charm.

How to copy files in specific location within multiple folders to a shared drive using windows command?

I need to copy several backup files to a shared folder
The Source to copy from looks like this below (there is other files inbetween but are not interested in copying them
C:\BackupLocation\BCK1\Logs\myLog1.log
C:\BackupLocation\BCK1\Logs\myLog2.log
C:\BackupLocation\BCK1\Logs\myLog3.log
C:\BackupLocation\BCK2\Logs\myLog1.log
C:\BackupLocation\BCK2\Logs\myLog2.log
C:\BackupLocation\BCK2\Logs\myLog3.log
C:\BackupLocation\BCK3\Logs\myLog1.log
C:\BackupLocation\BCK3\Logs\myLog2.log
I need to be able to copy any log file with the words "myLog" in the file name.
I thought about doing a For look do get the directory and then using robocopy to copy the files to my shared location
FOR /d /r %ROOT_SRC_BACKUP_LOCATION% %%G in (*logs*) DO (
Pushd %%G
Robocopy %%G "mybackup location directory" *mylog* /S
Popd )
But the problem is that the logs directory detects other logs directory... for example I have another logs directory in here
C:\BackupLocation\BCK3\server\Logs\IDontCareAboutTheLogsIntheServerDirectory.log
What is the most effective way to copy all the myLog's in the C:\BackupLocation\BCKXX\Logs\ folder?
Test this:
#echo off
Pushd "C:\BackupLocation"
for /d %%a in (bck*) do (
if exist "%%a\logs\" Robocopy "%%a\logs" "d:\mybackup location directory\%%a\logs" "*mylog*.log"
)
Popd

How can I move the contents of one directory tree into another?

I have a directory which contains files and a number of levels of subdirectories:
C:\Source
I would like to move the contents of C:\Source into:
C:\Destination
Requirements:
All files and all subdirectories
within C:\SourceData must be moved
I will be running the command in a
batch file
I can't use Powershell or
any other scripting languages
Attempt 0
XCOPY /E "C:\Source" "C:\Destination"
This works perfectly, but it copies instead of moves. I can't copy then delete the source as I'm moving a very large set of files and there isn't enough disk space to have two copies of them at a time.
Attempt 1
MOVE "C:\Source" "C:\Destination"
This moves the entire C:\Source directory into C:\Destination so I end up with:
C:\Destination\Source
Attempt 2
With some help from this question and accepted answer I came up with:
for /r "C:\Source" %%x in (*) do move "%%x" "C:\Destination"
This moves the files within C:\Source but not the subdirectories or their contents. Note that I used %%x instead of %x as I'm using it in a batch file.
Using FOR seems promising but I'm not sure I've used the right syntax? Have I missed something?
Attempt 3
As suggested by Nick D, I tried rename:
RENAME "C:\Source" Destination
For the example scenario I gave this works fine. Unfortunately my real Destination directory is at a different level to the Source directory and this doesn't seem to be supported:
C:\>REN /?
Renames a file or files.
RENAME [drive:][path]filename1 filename2.
REN [drive:][path]filename1 filename2.
Note that you cannot specify a new drive or path for your destination file.
I get "The syntax of the command is incorrect." errors if I try to specify a more complex destination path, for example:
RENAME "C:\Source" "C:\MyOtherDirectory\Destination"
RENAME "C:\Source" "MyOtherDirectory\Destination"
Undoubtedly use robocopy. It is a simple but brilliantly useful tool.
robocopy /move /e sourcedir destdir
This will move all the files and folders, including empty ones, deleting each original file after it has moved it.
If you don't have robocopy installed you can download it by itself or as part of a Microsoft resource kit.
Update:
Adjusted code to a. check whether folders already exist at the destination, in which case move files in that folder over (and continue traversing the source directory structure), otherwise move the folder wholesale.
At the end of the script the source folder is removed altogether to eliminate these folders which have had their files moved over to an already existent folder at the destination (meaning these folders have been emptied but not deleted at the source).
Additionally we check whether a folder is both empty and already exists at the destination in which case we do nothing (and leave the source folder to be deleted to the last line of the script). Not doing this results in "The filename, directory name, or volume label syntax is incorrect." errors.
Phew! Please let me know how you get on with this! I have tested this and it seems to be working well.
for /d /r "c:\source" %%i in (*) do if exist "c:\destination\%%~ni" (dir "%%i" | find "0 File(s)" > NUL & if errorlevel 1 move /y "%%i\*.*" "c:\destination\%%~ni") else (move /y "%%i" "c:\destination")
move /y c:\source\*.* c:\destination
rd /s /q c:\source
In response to ufukgun's answer:
xcopy C:\Source\* C:\Destination\* /s /e /i /Y
/s - Copies directories and subdirectories except empty ones.
/e - Copies directories and subdirectories, including empty ones. Same as /S /E. May be used to modify /T.
/i - If destination does not exist and copying more than one file, assumes that destination must be a directory.
/y - Suppresses prompting to confirm you want to overwrite an existing destination file.
As stated in another answer, using xcopy may be not as efficient as it would be a native move command that only changes pointers in the filesystem.
Since XCOPY works, you could use XCOPY and DELETE, it's a workaround, but should work?
on Vista use
robocopy source destination /MIR
/MIR .. mirror a complete directory tree (also deletes files in the destination)
else
xcopy
Of course you have to delete the source afterwards :)
I have a directory which contains
files and a number of levels of
subdirectories:
C:\Source
I would like to move the contents of
C:\Source into:
C:\Destination
Maybe I'm missing something, but can't you just rename the folder?
As sent on twitter:
Try combining attempt 3 with attempt 1. Rename to get the destination folder correct, then move "Destination" to the correct place.
#echo on
set SOURCE=C:\Source
set DESTINATION=C:\Destination
xcopy %SOURCE%\* %DESTINATION%\* /s /e /i /Y
PAUSE
i use batch file like this...
or simply call:
xcopy C:\Source\* C:\Destination\* /s /e /i /Y
I use a utility called xxcopy. It can move files and have many useful options, you can use it like this :
xxcopy C:\Source C:\Destination /E /RC
the options :
/E to copy everything even empty folders
/RC to remove every source file after each successful copy
you can download free copy of xxcopy for personal use from :
http://www.xxcopy.com/xcpydnld.htm
Maybe a little off-topic, but still usefull:
Some people suggest to just copy + delete the source files, but
moving files is not the same as copying + deleting!
When using the (x)copy function, you allocate new space on the same volume on a harddisk. After the copying the files, the old files (the old allocated space which was required for the files) are beign marked as deleted. While you will achieve the same result as an end-user, moving does something diffrent and more efficient.
Moving files actually only changes some records in the MFT (master file table). These changes only consist of a different path for the user to locate its files. Physically the files still remain in the same sectors on the harddisk.
If all your trying to do is move a directory and the content up one level:
MOVE folder_you_wan_to_move ..
Note that .. refers to the next directory up.
I leave this code I have written based on ljs's attempt,
It moves directory trees as Windows does, overwriting the files that already exists in destination with those in source, and avoiding the slow copy and erase method except if the destination is in a different drive.
If your S.O is not in english must change line 6 with the text used by the Dir command when it finds 0 files.
movedir.bat source_dir destination_dir
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
if %1.==. echo movedir dir1[\*] dir2 & echo move dir1 inside dir2 overwriting coincident files & echo option \* moves only dir1 content & goto end
set S=%~f1
set D=%~f2
set "noFiles= 0 File"
set "R=0" rem R is option [\*] flag
if %S:~-2%.==\.. set "S=%S:~,-2%" & set "R=1"
if not exist "%S%" goto paramERR
if not exist "%D%" goto paramERR
set "Trim=0" & set "Sc=%S%"
:LP
set /A Trim+=1 & (set "Sc=!Sc:~1!") & if NOT !Sc!.==. goto LP
if %R%==0 (if exist "%D%\%~n1%~x1" (set "D=%D%\%~n1%~x1")) else move /y "%S%" "%D%" & goto end
CALL:movefiles "%S%" "%D%"
for /D /R "%S%" %%I in (*) do (set "Way=%%~fI") & (set "Way=!Way:~%Trim%!") & if exist "%D%!Way!" (CALL:movefiles "%%I" "%D%!Way!") else (move /y "%%I" "%D%!Way!\.." > NUL)
rd /s/q "%S%" & if %R%==1 md "%S%"
goto end
:movefiles
dir %1 | find "%noFiles%" > NUL & if ERRORLEVEL 1 move /y "%~1\*.*" %2 > NUL
goto :eof
:paramERR
echo Source or Destination does not exist
:end
I think the easiest thing you could do is to modify your Attempt 2
from
MOVE "C:\Source" "C:\Destination"
to
MOVE "C:\Source\*" "C:\Destination"
KISS ;-)
Edit: this seem not to work, so my advice is to trash away the crappy DOS command line and use Cygwin with BASH as a shell! (or just add the cygwin binaries to the path so you can use mv within DOS, thus not having to change the shell as your requirements state).

Resources