Completely new to scripting, tried to find a solution through searching the web but I'm stumped, so asking for help please!
I'm trying to use robocopy with a variable as both the source and destination, different one for each, but I just can't get the right syntax.
The hard code which I can get to work fine is:
robocopy C:\Users\me\Documents\a C:\Users\me\Documents\b
But I can't get it to work with variables. I've tried, after reading around, what seems like all variations of the below with " and % in/out, with and without Set, and none of them have worked.
Set src="C:\Users\me\Documents\a"
Set dest="C:\Users\me\Documents\b"
robocopy %src% %dest%
Hope that's a clear explanation of what I'm trying to do, if not ask for clarification.
Thanks in advance for any help.
set "src=C:\Users\me\Documents\a"
set "dest=C:\Users\me\Documents\b"
robocopy "%src%" "%dest%"
Nothing bad with your sintax. This way is "more robust" or more standard or more habitual, ...
BUT robocopy is not copy not xcopy. You are asking robocopy to copy from source to target changed or new files. If there are no changes, robocopy will not copy anything. If you have tried and it worked, .... if no changes, no file copy.
AND you have not asked robocopy to copy subdirectories. So, if there are no files in source directory, nothing will be copied.
I have found Robocopy is touchy to the point of being arbitrary about syntax. I have found a similar problem to yours:
This code works:
Set Today=%DATE:~0,3%
Robocopy "G:\folder A" "U:\%Today%\folder A" ^
/S /XJD /R:25 /W:4 /NP /copyall ^
/LOG:"U:\%Today%\FolderALog.txt"
IF ERRORLEVEL 8 goto Badend
This (nicely structured) code doesn't work
Set Today=%DATE:~0,3%
Set source="G:\folder A"
Set target="U:\%Today%\folder A"
Set Logname="U:\%Today%\FolderALog.txt"
Echo Source is %Source%
Echo Target is %Target%
Echo logfile named %Logname%
Pause
Robocopy %source% %target% ^
/S /XJD /R:25 /W:4 /NP /copyall ^
/LOG:%Logname%
Pause
However, in this 2nd example, take the 1st continuation out of the command line and it works:
Set Today=%DATE:~0,3%
Set source="G:\folder A"
Set target="U:\%Today%\folder A"
Set Logname="U:\%Today%\FolderALog.txt"
Echo Source is %Source%
Echo Target is %Target%
Echo logfile named %Logname%
Pause
Robocopy %source% %target% /S /XJD /R:25 /W:4 /NP /copyall ^
/LOG:%Logname%
Pause
I've been using the caret (^) as a continuation character in batch command jobs ever since the DOS days, but in this instance the parser tries to concatenate it with the previous variable and the job dies because the system thinks I'm trying to name a folder "U:\%Today%\folder A ^". So goes it -- you keep trying things until something works.
Troubleshooting techniques: Doing Echos of newly defined variables then pausing allows you to check for typos and misplaced quote marks. The pause at the end gives you ample time to read the error code, should there be one. Another thing I ran into once was inadvertently inserting an unprintable character in place of a space in a path enclosed with quotes.
RoboCopy is very powerful and well worth occasional tinkering with touchy syntax.
Looks like an old question, but I ran into this issue myself today and solved it by using double slashes for the set command:
Set src="C:\\Users\\me\\Documents\\a"
Set dest="C:\\Users\\me\\Documents\\b"
robocopy %src% %dest%
Try this way
Set src=C:\Users\me\Documents\a
Set dest=C:\Users\me\Documents\b
robocopy %src% %dest% /E
/E - for copying of Subfolder including empty subfolder
If you are trying to use a .bat the code will be like this:
Set src="C:\Users\me\Documents\a"
Set dest="C:\Users\me\Documents\b"
robocopy.exe %src% %dest%
You forgot to put the .exe
dude try the XCOPY command it will work for sure!
example:
xcopy "C:\Users\me\Documents\a" "C:\Users\me\Documents\b"
it will ask is the destination is a folder or a file, so once u chose folder (dir) it will copy!
hope it helps! :D
Related
I'm trying to create a batch file in Win7 that will copy any files that have been created or modified today and copy them to a destination with a similar directory structure. This is what I have so far:
set today="20180721"
robocopy "C:\temp\" "D:\backup\temp\" *.* /s /DCOPY:T /MINAGE:%today%
I know that /e copies empty directories and /xf excludes all files, but I'm not sure if that helps me. The code above seems to copy all files regardless of date, so I'm a little lost here.
Assigning quotes to your variables is not a best practice and will cause problems with some commands if you try to quote the variable later on. Regardless that was not your problem. Your problem is you need to use the /MAXAGE option. Reading the help file you should see this:
/MAXAGE:n : MAXimum file AGE - exclude files older than n days/date.`
So your code should be:
set "today=20180721"
robocopy "C:\temp\" "D:\backup\temp\" *.* /s /DCOPY:T /MAXAGE:%today%
Going to assume you thought the options were for INCLUDE.
robocopy's /MINAGE//MAXAGE options regard the full date and time, so specifying something like /MAXAGE:1 filters for files that have been modified within the last 24 hours.
If you want to process files which have been modified today only, hence regarding the date but not the time, you could use forfiles and its '/D' option, like this:
set "DEST=D:\backup\temp"
forfiles /P "C:\temp" /D +0 /C "cmd /C if #isdir==FALSE for %%Z in (#relpath) do #(2> nul md 0x22%DEST%\%%~Z\..0x22 & copy #relpath 0x22%DEST%\%%~Z0x22)"
I have a folder xyz. It has a batch file which copies files from source directory abc to destination directory def. I am using copy with options /v /y.
Copy works absolutely fine. But I notice a strange or weird issue that additionally a copy of all the files copied from source to destination are present in folder xyz.
I started observing this issue after a system restart and not sure if its a one time issue. But I would like to know if someone has run into this issue before and what is the possible fix?
Here is the code:
#if not defined ECHO_ON echo off
SETLOCAL EnableDelayedExpansion
set arg1=%1
set arg2=%2
copy /v /y !arg1! !arg2!
call :getPath !arg1!
ren !arg2!\!_NAME_EXT! !_NAME!.svg
:getPath
set _NAME=%~n1
set _NAME_EXT=%~nx1
set _LOC=%~dp1
goto:eof
endlocal
Please note I am using copy and robocopy command (for some other copying operation) in same .bat file.
Is this something to be worried about?
(As I wrote things worked fine until restart.)
Your double Copy is because a batch script works line by line until it reaches an end of file marker or an exit instruction. A Call command returns back to the point just after the Call instruction. When it returns, there is no exit instruction or end of file marker until the bottom of your script, so the :getPath label is executed again.
There appears to have been absolutely no reason for EnableDelayedExpansion in your script, for Setting any variables or for a Call command. I have therefore simplified it as such:
#Echo Off
If "%~2"=="" Exit /B
If Not Exist "%~2\" MD "%~2" 2>Nul || Exit /B
If Exist "%~1" Copy /V /Y "%~1" "%~2\%~n1.svg"
I hope it helps you out.
Here is what I have so far:
IF EXIST "C:\Program Files (x86)\Yawcam\Yawcam.exe" GOTO :eof
ELSE
start \\hazel\software$\YawCam\v6.0\yawcam_install.exe /SP- /VERYSILENT
xcopy "\\hazel\software$\YawCam\Doc Cam.lnk" "C:\users\public\desktop\Doc Cam.lnk" /C /Y
:eof
pause
EXIT
Now, it installs properly, but doesn't create the shortcut. I have tried so many different combinations of switches, quotes, and statements. I just can't seem to get it to work. I would very much appreciate any help with this, because I'm sure it is just something I have simply overlooked. Thank you in advance!
The following rewrite requires to be run As administrator.
If Exist "%ProgramFiles(x86)%\Yawcam\Yawcam.exe" GoTo :EOF
"\\hazel\software$\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT
XCopy "%~dp0Doc Cam.lnk" "%PUBLIC%\Desktop" /C /Y
Pause
I would write it like this:
pushd "\\hazel\software$" || exit /B 1
if not exist "%ProgramFiles(x86)%\Yawcam\Yawcam.exe" (
".\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT
)
copy /Y ".\YawCam\Doc Cam.lnk" "%PUBLIC%\Desktop\Doc Cam.lnk"
popd
exit /B
What I did, and why:
added pushd to resolve the UNC path \\hazel\software$ as some commands might have trouble with such; || means to execute next command in case of failure, exit /B 1 exits the batch file if pushd fails, like when the path could not be found; popd at the end restores the previous working directory finally;
reversed the if query as you want something to happen in case the condition is not met; this also avoids the need of goto; in addition, never define a label :EOF as this is a reserved name (see this: goto); regard that your if/else syntax is wrong!
used environment variables for system paths, like %ProgramFiles(x86)% and %PUBLIC%, because the directory locations may be different on some systems;
removed the start command as it is usually not necessary to run external (console) programs; (if it is required for this application for some reason, you might want to change the syntax to: start "" /WAIT ".\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT)
replaced xcopy by copy since you are copying a single file only, in order not to having to deal with the F = file, D = directory prompt;
added switch /B to exit in order to just terminate the batch file but not the hosting command prompt (cmd) instance;
I'm not sure if this method is necessarily the best way to go about it, but it got it working for our needs! I appreciate all your guys' help with this! We looked at each comment/answer and went from there. Thank you!
Here's what we did in the end:
IF EXIST "C:\Program Files (x86)\Yawcam\Yawcam.exe" GOTO eof
ELSE
start \\hazel\software$\YawCam\v6.0\yawcam_install.exe /SP- /VERYSILENT
:eof
Echo F|xcopy "\\hazel\software$\YawCam\Doc Cam.lnk" "C:\users\public\desktop\Doc Cam.lnk" /C /Y
EXIT
Hopefully this can help someone trying to do the same in the future!
I am trying to make simple security program for my company.
We usually make a lot of doc or ppt(x) files and
for some reason, we need to make them disable as soon as possible.
So we usually deleted the all of files but It took so long.
So I thought I can do that by overwritting the files.
If I have a empty doc or ppt files then overwite all of doc, ppt files in working drive each, then it will be faster and much safer than just deleting.
So I tried to use xcopy
Assuming empty.doc is just empty doc file and
xcopy /s /y c:\users\mycom\empty.doc c:\*.doc
But it said cannot perform cyclic copy
I need you guys help
and I am glad to hear suggestion.
Thanks.
This is an old, old batch file that I employed for such an endeavour:
:: dispose.bat
#echo off
:: Check parameter(s), stripping quotes
set yp1=%1
set ydf=
:insistp1
if defined yp1 set yp1=%yp1:"=%
if not defined yp1 for %%i in (echo goto) do %%i error - filename required
if not exist "%yp1%" for %%i in (echo goto) do %%i error - file not found
for %%i in ("%yp1%") do (set yfr=%%i&call :zapit %%~di) 2>nul
:error
:: Clean up variables used
if defined ydf echo Warning! dispose failed!!
for %%i in (yp1 yfr yrn ydf) do set %%i=
goto :eof
:zapit
set yfr=%yfr:"=%
IF /i %1 == u: DEL "%yfr%" &goto :eof
if not exist %1\delete\. md %1\delete
(set yrn=)
:rndloop
set yrn=%yrn%%random%
if exist %1\delete\%yrn% goto rndloop
if not exist "%yfr%" set ydf=Y&goto :eof
move "%yfr%" %1\delete\%yrn%>nul
goto :eof
:: dispose.bat ends
Noting that u: is a RAMDRIVE on my system, hence mere deletion is all that is required.
The purpose is not to actually delete the files, but to move them to a directory named ?:\delete and provide them with a random name in that directory.
Since the file is simply MOVEd it is quite fast, which addresses your time consideration.
An issue for me is the idea of copying a file over all of the files you target. If the file that you copy is shorter than the other files, some data wilstill be available to be recovered. Regardless, it will alwats be slower than simply deleting the files (which you say you are currently doing.)
This scheme simply accumulates the files-to-be-deleted in a known directory on the same drive (so they will simply be moved, not copied.)
Once they are in your \delete directory, you can let a utility like ccleaner or recuva loose on that single directory in the background and it will overwrite the files a specified number of times.
Here's a simpler method. Be careful.
At the command line:
for /r c:\ %A in (*.doc? *.ppt?) do echo. > %A
In a batch file:
for /r c:\ %%A in (*.doc? *.ppt?) do echo. > %%A
EDIT:
To replace with a file, see the example below. Replace the example's d:\path\file.ext with your intended file. Note that the previous option will work much faster with a similar result.
At the command line:
for /r c:\ %A in (*.doc? *.ppt?) do copy d:\path\file.ext > %A
In a batch file:
for /r c:\ %%A in (*.doc? *.ppt?) do copy d:\path\file.ext > %%A
Either way, as noted in Magoo's answer, larger files will still have recoverable data on the drive. You stated in a comment:
But if I overwrite the original files, then they cannot guess what it
was unless they got bak files
This isn't accurate. Forensic tools can retrieve the partial data that wasn't overwritten with new content.
I'm very new to scripting in batch so please bear with me.
My goal is so as to move files which have the same filenames but with different extension; such as i want to move myfile.txt.1 and myfile.txt.2 without 'touching' myfile.txt
I've managed to use the wildcard * but it logically moves even the file which i don't want to move.(i.e. myfile.txt)
My question is... I was thinking of using a for loop to count files and using the "count" variable instead of the * , but is there a more direct way of implementing this script?
Attaching my script:
cd my_path
mkdir test
robocopy "src" "dest" "my_file.*"
echo The file was moved succesfully !!!!
I think robocopy should be able to handle your needs.
I would have expected the wildcard "my_file.txt.*" to work, but interestingly it still matches my_file.txt despite the lack of a trailing ..
But adding the /xf option to exclude the "undecorated" filename works for me:
robocopy "src" "dest" "my_file.txt.*" /xf "my_file.txt"
#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
SET destdir=c:\destdir
FOR %%i IN ("%sourcedir%"\*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%destdir%\%%~nxi" (
ECHO CAN NOT MOVE "%%~fi" "%destdir%\%%~nxi"
) ELSE (ECHO MOVE "%%~fi" "%destdir%\%%~nxi")
)
GOTO :EOF
This should accomplish the task AAUI. It also detects the presence of a clashing filename in the destination directory. Simply remove the ECHO from the ECHO MOVE to activate after verifying your test. Personally, I'd leave the ECHO CAN NOT MOVE as-is to report a problem. Changing that to MOVE has the potential to overwrite an existing file.