i need something that will move files from one folder to another network location, but leave any locked files that are currently being written to!
any ideas?
apols i am no developer, but i have been trying to use
ROBOCOPY C:\test c:\test\q /move /R:0 /W:0
but even if i open a file, it still moves it to the new directory
mal
You can use for %%f in (*) do move %%f destination\%%f (in a batch file) and just allow each individual invocation of move to fail, watching the errors scroll by.
There are also options for making for %%f work recursively, though that's a bit involved.
Related
Context
I'm trying to make a batch script that can be thrown into a pre-existing folder and upgrade it. Imagine a folder that looks like this:
domfolder
LICENSE
merge_new_stuff.bat
words.txt (has 6 words)
awesomefolder
garfield.png
upgrade_assets
upgradeinfo.txt
new_files
words.txt (has 7 words)
awesomefolder
odie.png
awesomest
MONKEY.txt
subfolder
subsubfolder
numbers.txt
The sole purpose of merge_new_stuff.bat is to take everything inside the new_files folder, and bring it into domfolder, replacing any pre-existing files like words.txt, leaving anything else alone, and getting rid of the upgrade_assets folder. So if everything goes right, the folder structure should like this after running:
domfolder
LICENSE
merge_new_stuff.bat
words.txt (has 7 words)
awesomefolder
garfield.png
odie.png
awesomest
MONKEY.txt
subfolder
subsubfolder
numbers.txt
What I've Tried
First instinct is to just use a simple move command: move /y upgrade_assets\new_files\*
That upgrades words.txt, but it totally ignores the folders. Only part of what I want.
I tried a for loop to see if it'd be different somehow, same results:
for %%A in (upgrade_assets\new_files\*) do move /y %%A
Next, I tried looping through dir results alongside the basic move:
for /f "tokens=*" %%A in ('dir /b /s /a:d "upgrade_assets\new_files"') do move /y "%%A\*.*" "%~dp0%%~nxA"
This almost worked, properly moving odie.png and subfolder\subsubfolder\numbers.txt. But once it tries to move MONKEY.txt, it... decides to make a file called "awesomest" that has the contents of MONKEY.txt? So clearly, it doesn't handle going down pre-existing folders, which is definitely not helpful.
Looking around, I only found one thread that seems close to what I want. Most of the replies mention xcopy/robocopy, but I want to avoid the copy/delete method as much as possible considering the potential size of updates. And when I changed the accepted answer to fit what I'm doing, it still had issues going more than one folder deep.
for /d /r upgrade_assets\new_files %%A in (*) do (
if exist "%~dp0%%~nA" (
dir "%%A" | find "0 File(s)" > NUL
if errorlevel 1 move /y "%%A\*.*" "%~dp0%%~nA"
) else (
move /y "%%A" %~dp0
)
)
I'm pretty sure the issue is centered around %~dp0%%~nA, I need a way to have it read more than just the folder the file being copied is in, which is all %%~nA shows.
Preferably, the solution should be completely independent of what actual files are in the folder, so it can be used with any update. If I need external tools, I would like them to be free/libre software if possible. I'm running Windows 10, but I know this script will be run by people using Windows 7.
Quite frankly this will do exactly what you want.
robocopy .\upgrade_assets\new_files\ . /E /MOVE
It will create the directories and files as well as delete from source once done.
Most companies I have worked for start new projects with a templated folder structure. Windows will automatically flag empty folders (the icon shown in the file explorer is that of an empty folder) however, folders whose subfolders are also empty will not be flagged (their icon shows a folder containing files). This can create confusion and lead to mistakes during the early stages of a project as it would appear at a glance that some folders have had their content added when they really only contain empty subfolders.
So my question is:
How can I iterate over folders with empty subfolders and "flag" them via the use of a Batch file.
The .bat file would need to search through subfolders to determine if a folder has any real content. If the folder does not have real content then the .bat file would need to flag it (flagging could be done with a change of its icon or filename). This would make it much easier to navigate new projects with large templated folder structures.
I don't need a completed file, I would just like to know how it could be achieved. However, any tips or suggestions on how to achieve this functionality would be more than welcome!
*Edit
Just to clarify I will show an example:
If I create an empty folder called 'Project' it will display with the Empty Folder icon. As shown Below:
Now I will add a new folder to my project folder called 'I am Empty':
The folder 'Project' no longer displays with the Empty Folder icon. It now uses the icon that shows it with content. As shown Below:
What I want is a .bat file that will parse the contents of the 'Project' folder and determine that it only contains the 'I am Empty' folder, which is empty and "flag" that folder (to flag it we could change the icon of the 'Project' folder back to the Empty Folder icon, change the name or "gray it out"). As shown Below:
cd example
for /d %%i in (*) do #dir /b /s /a-d "%%i">nul 2>&1|| #echo "%%i" has no files
give for an additional /r if you want to check subfolders too.
The trick is to list files only (/a-d) in the folder and all subfolders (/s) and if this fails (||) (because there are no files), do something with this folder (just echo here, but rd /s /q or ren is also possible)
Building on the answer given by Stephan and looking at other related stack exchange posts I pieced this solution together and it works well for my needs:
#ECHO OFF
PUSHD "%~dp0"
FOR /f "tokens=* delims=" %%F in ('dir /b/s/ad *') DO (
#dir /s /a-d-s "%%F">nul 2>&1|| ATTRIB +H "%%F"
#dir /s /a-d-s "%%F">nul 2>&1&& ATTRIB -H "%%F"
)
POPD
EXIT
I opted for a solution that did not modify file names. While testing that approach I realized it doesn't create the best user experience.
Instead, running this batch file hides the folders that are effectively empty and if your folder settings allow you to see hidden folders then they appear faded out. It also re-shows hidden files that have new content since the last time the batch file was ran.
For those of you coming to this solution who, like myself, are relatively inexperienced with batch scripting. I will explain what the code does and why (as I understand it).
I don't want to change the batch file for each implementation so I call PUSHD "%~dp0 to set the active directory to the folder containing the batch file (this lets me include the batch file in the folder-structure template, which is copied and pasted for each project)
Since I decided to use the hidden attribute for folder flagging, I needed to modify the FOR loop . FOR loops typically ignore hidden files which becomes troublesome if you need show a file that was previously hidden because it has new content. Running FOR /f "tokens=* delims=" %%F in ('dir /b/s/ad *') DO ()
allows the batch file to loop through all files mainly because of the /f attribute, but check out
this post about looping through hidden folders for more information.
Inside the for loop I am pretty much doing what Stephen suggested in his answer with the added logic to remove the hidden attribute on folders that no longer need it.
The only thing this batch file is lacking, is the ability to auto update on folder modifications or to auto-run on folder open (I hear this might be possible with an .ini file?) however, for my needs it will suffice to rerun the batch file, manually, after making changes to the folder.
Batch scripting is way outside of my comfort zone as far as scripting languages go so please forgive and correct me if I have made any mistakes or if there is a more reliable way to do what I need.
Every month I have a very large number of files (in many subfolders) in a particular folder. I need to move them all into a different folder. In an attempt to automate the process of moving them I used robocopy in a batch file. It works fine, but takes HOURS to run. (It is many many GB).
Now, if I do it manually in Windows Explorer, by opening said folder, selecting all, and right-dragging to destination folder, and choosing "Move Here", it moves INSTANTLY. (Windows XP must be pruning and grafting the directory entries, without ever making a second copy of the files. ... and yes, source and destination are on same partition.)
So, QUESTION IS: Does anyone know of a program I can run from a batch file to move files in this instantaneous way? (need to move entire sub-folder tree)
You can use MOVE for this:
C:\>MOVE /?
Moves files and renames files and directories.
To move one or more files:
MOVE [/Y | /-Y] [drive:][path]filename1[,...] destination
To rename a directory:
MOVE [/Y | /-Y] [drive:][path]dirname1 dirname2
[drive:][path]filename1 Specifies the location and name of the file
or files you want to move.
destination Specifies the new location of the file. Destination
can consist of a drive letter and colon, a
directory name, or a combination. If you are moving
only one file, you can also include a filename if
you want to rename the file when you move it.
[drive:][path]dirname1 Specifies the directory you want to rename.
dirname2 Specifies the new name of the directory.
/Y Suppresses prompting to confirm you want to
overwrite an existing destination file.
/-Y Causes prompting to confirm you want to overwrite
an existing destination file.
The switch /Y may be present in the COPYCMD environment variable.
This may be overridden with /-Y on the command line. Default is
to prompt on overwrites unless MOVE command is being executed from
within a batch script.
For example:
C:\Users\test>mkdir to
C:\Users\test>move from\*.txt to
C:\Users\test\from\1.txt
C:\Users\test\from\2.txt
2 file(s) moved.
With a point in the right direction from #psmears, and a lot of googling, I found the (or a) solution:
#echo off
setlocal ENABLEDELAYEDEXPANSION
REM ** Change to source dir
L:
cd "L:\Backups\Source"
REM ** Move files recursively
for /R %%G in (.) do (
set mydir=%%G
set mynewdir=!mydir:~18!
md "L:\DEST\!mynewdir!"
cd "L:\DEST\!mynewdir!"
move "%%G\*.*" .
)
REM ** Remove now-empty sub-dir structure inside source
L:
cd "L:\Backups\Source"
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
I need to create a .bat that runs through a multilayered directory... copying certain files that contain the following suffix: '.full.jpg' to save as '.jpg'
What I've tried:
copy /y "C:\Users\myname\Desktop\maindir\*.full.jpg" "C:\Users\myname\Desktop\maindir\*.jpg"
However, I cannot get it to work.
The .bat is located in the 'maindir' directory and ran from the terminal (cmd).
Here's an example scenario that maps closely to mine:
Existing Files:
C:\Users\myname\Desktop\maindir\a\a\picture1.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.full.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.full.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.full.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.full.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.full.jpg
Example Output Wanted:
C:\Users\myname\Desktop\maindir\a\a\picture1.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture1.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.full.jpg
C:\Users\myname\Desktop\maindir\a\a\picture3.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.full.jpg
C:\Users\myname\Desktop\maindir\a\b\picturea.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\a\b\pic1.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.full.jpg
C:\Users\myname\Desktop\maindir\b\a\foto.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.full.jpg
C:\Users\myname\Desktop\maindir\b\a\photo.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.full.jpg
C:\Users\myname\Desktop\maindir\b\b\pic1.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.full.jpg
C:\Users\myname\Desktop\maindir\b\c\pi2.jpg
I'd appreciate any help towards this as I haven't been able to do it yet. I will run across a directory structure whereby the top level directory will contain 15+ directories and each containing 20+ directories with 100+ files in each lowest directory.
Thanks.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\Users\myname\Desktop\maindir"
FOR /r "%sourcedir%" %%a IN (*.full.jpg) DO (
FOR %%b IN ("%%~dpna") DO ECHO(COPY "%%a" "%%~dpnb.jpg"
)
GOTO :EOF
The inner for examines the drive-path-name only of the complete filename in %%a (ie. it drops the .jpg) and delivers the drive-path-name of that name (ie. drops the .full) to which you add .jpg and job done.
You would need to change the setting of sourcedir to suit your circumstances.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files.
I am trying to write a Windows Batch file that will allow me to move all directories within a given source directory into a target directory that exists within that source directory.
Obviously my move command with need to only apply to directories and also exclude the target directory from being processed.
Is this possible with a Windows batch command?
Robocopy (present in recent versions of windows or downloadable from the WRK) can do this, just use the /xd switch to exclude the target directory from the copy;
robocopy c:\source\ c:\source\target\ *.* /E /XD c:\source\target\ /move
FOR /d %%i IN (*) DO IF NOT "%%i"=="target" move "%%i" target
That won't work - you'll get an error telling you the target directory is inside the source directory or so, even if you explicitly exclude the target directory. What you can do is move the directories to a temporary location which is not under the source, and then move them into the target.
BTW, using the move command won't let you specify folders to exclude. For that you can use xcopy, but note that it will copy the folders, as opposed to move them. If that matters, you can delete whatever you want afterwards, just make sure you don't delete the target dir, which is in the source dir...
Using robocopy included with Windows 7, I found the /XD option did not prevent the source folder from also being moved.
Solution:
SET MoveDirSource=\\Server\Folder
SET MoveDirDestination=Z:\Folder
FOR /D %%i IN ("%MoveDirSource%\*") DO ROBOCOPY /MOVE /E "%%i" "%MoveDirDestination%\%%~nxi"
This loops through the top level folders and runs robocopy for each.
NB: Robocopy mentioned above using the /move flag will copy the files and then delete them from the source folder rather than moving the files. This may be critical if moving large numbers of files from one location to another on the same disk (because move is virtually instantaneous, while copying is a much slower operation)
On windows batch:
FOR /d %%i IN (MySourceDirectory\*) DO move "%%i" MyTargetDirectory\%%~ni
The above command moves all directories found in MySourceDirectory (/d) to MyTargetDirectory using the original directory name
(~ni) Robocopy's move first does a copy, then delete, so it is slower.
This works for me:
move c:\fromDir\*.* c:\toDir\