I'm a mortgage loan guy in Seattle, WA and I frequently set up a folder hierarchy into which I save a client's documents and as they come in to me. I've been creating these manually for years and I'd like to save the 3 to 4 minutes it takes to set these up by using a batch file.
So... I have a default set of folders, some of which contain a couple of small Adobe PDFs. What I'd like to do (and cannot make happen) is to run a batch file that would facilitate some custom remarks or input from me during the batch so that with a click and a couple of keystrokes, I have an organized folder setup for a new client within seconds rather than minutes.
I've written the following but it isn't producing any output folders or files.
______not sure character terms show correctly - see linked images below for actual______
#echo off
::Ask
echo Your Source Path:
set INPUT1=
set /P INPUT1=Type input:
echo Your Destination Path:
set INPUT2=
set /P INPUT2=Type input:
C:\WINDOWS\system32\xcopy.exe /e /v %INPUT1% %INPUT2%
My responses were:
to the first prompt "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014"
to the second prompt "E:\DV8333 MY DOCUMENTS\001 CLIENTS\"
I have verified that xcopy.exe is in fact located as indicated above.
I'm on XP SP3
My actual paths and .bat file are shown in the linked image for clarity.
http://www.avidrecording.com/images/01.png
Thanks in advance, much appreciated.
#Rem save this as a .bat file and run
#echo off
set /P source=Enter Source Folder:
echo %Source%
set /P destination=Enter Destination Folder:
echo %destination%
xcopy %source% %destination% /v /i /e
Fundamentally, your problem appears to be that the xcopy command can't figure out which of the data it is receiving is parameters and which switches and which superfluous because you have spaces in your directorynames.
Fortunately, the cure is simple. "quote your parameters"
C:\WINDOWS\system32\xcopy.exe /e /v "%INPUT1%" "%INPUT2%"
Now - the path to xcopy.exe is probably superfluous - as is the extension, so
xcopy /e /v "%INPUT1%" "%INPUT2%"
is more than likely all you'd need.
(I'd caution to experiment with a throw-away destination until you've perfected your method. I use a RAMDISK...)
Also, if you're copying a template, then there's no apparent reason for all the folderol about inputting Input1. If you have more than one template set, set up a separate batch and shortcut for each one with a fixed template path, eg
xcopy /e /v "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014" "%INPUT2%"
Note the use of quotes to defeat the evil spaces.
Next, your destination could be built, but may contain spaces. For instance, you may have a client to which you wish to refer as "037 - Fred Nurk". Now it's a pain to have to type in the full path, so make it easy. Just type in the 037 - Fred Nurk part and let batch fill in the rest.
xcopy /e /v "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014" "E:\DV8333 MY DOCUMENTS\001 CLIENTS"\"%input2%"\
Note that this will append the input as a directory under E...001 clients. Note that the strings are concatenated and the double-quotes are there solely to tell batch "here be a string that may contain spaces."
If this works, and there's no reason why it wouldn't (does for me...) then all you'd need to do is enter the client details and the template would be copied to a new directory. Now actually playing around with the data in the files that are copied so that they are customised - well, at the price, that would be worthy of another question...
#echo off
echo Backing up file
set /P source=Enter source folder:
set /P destination=Enter Destination folder:
set /P Folder name=Enter Folder name
set xcopy=xcopy // Set the switches as per your need
%xcopy% %source% %destination%
pause
Related
I am trying to delete the sub folders using batch file.
I have folder
c:\users\mis
c:\users\mis\A\Third Party Log
c:\users\mis\B\Third Party Log
c:\users\mis\C\Third Party
c:\users\mis\D\Third Party
Etc.
I want to delete all "Third Party Log" folder and I tire as below:
#echo off
Set MainFolder=C:\users\mis
FOR /D %%D IN ("%MainFolder%\*") DO CALL :RENAME %%D
pause & exit
REM -------------------------------------------------------
:RENAME
Set CRITERIA=Third Party Log
FOR /D %%R IN ("%1\%CRITERIA%") do #if exist "%%R" rd /s /q "%%R"
REM -------------------------------------------------------**
If the folder is only Third it is deleting. Please help me deleting the fodlers.
Thanks,
Htet
#ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "targetdir=u:\your files"
SET "selectname=Third Party Log"
FOR /f "delims=" %%a IN (
'dir /b /s /ad "%targetdir%\%selectname%" '
) DO (
IF /i "%%~nxa"=="%selectname%" ECHO RD /S /Q "%%a"
)
Simply perform a dir /b /ad to list all of the directorynames matching the mask %selectname% and remove all of the hits.
Note that the for loop could be condensed to a single line, but I've split it over a number for clarity.
Naturally, the variables could be substituted by their literal values as well, if desired. This would reduce the entire batch to a single line which could be entered directly at the prompt in which case each %% needs to be reduced to a single %.
Posted code simply echoes the proposed instruction to allow for verification. I the displayed instructions are correct, remove the echo keyword to actually destroy the unwanted directories.
Finally, in your original code, rename is not a good name for the subroutine for two reasons : First, it is misleading as no renaming is being performed and second, ren is an alias of rename - and it's not a good idea to have a routine or variable or label that is itself a command-name.
I can sadly not write code and test it rn but:
You could use the dir command into a temp file.
Use findstr(or find i m not shure) and look for third party log.
Write this back to the temp file.
Now you should be left with a file filled with the paths of the folders you want gone.
Read the file line by line and delete and use this line string to provide the path for the del command.
To change the name as in the sample code you could take the line string and use it as the path to the ren command.
This is most likely a very bad approach but it should work.
this is my first question, so I apologize beforehand if I write not as you are used to...
fact:
I've a deep folder structure with tons of files (images,videos and so on) so I want to copy that files to a flat structure for a better overview.
I want to keep (at least) the original date attributes: creation-date and last-modified date.
Problem 1) there are files with same name 00001.jpg in different folders which I want to have in same folder, so I want to add creation date/time to filename on copy process.
00001.jpg becomes 2015-11-17_11-23-35_00001.jpg
So far so good. Or not good...
Copy and XCopy doesn't give me an option to do that, without loosing at least the creation date information (I didn`t find a solution with both).
Now I try to copy the files (file by file) with robocopy to new folder and use ren on the copied file to "pre-set" the date/time information before the filename.
Here is a simple test.bat example:
setlocal enableextensions enabledelayedexpansion
robocopy . ./zzz original.txt /copy:DATSO
pause
rem :: formatted creation date of original file will be here, in real life
set "myDate=2015-11-17-_11-23-35"
rem rename "./zzz/original.txt" "!myDate!_renamed.txt" ::doesnt work: why? relative path??
rem :: this will do what I want - original creation date is kept on copy file
FOR %%A IN (zzz/original.txt) DO REN "%%~fA" "!myDate!_%%~nxA"
[possibly] Problem2) Is there a better way to do this, or could I run into thread problems (asynchronous execution). Could it be, that I try to rename a file before the robocopy has finished the copy process (e.g. for large files)?
Sorry I'm a totally batch newbie (also as poster in SO ;).
ThanX in advance for each tip and also for critics on my solution approach. Maybe I have the horse-blinkers on my head and dont see the easy solution?!
[edit: formatting of post]
[edit: content of post -> date/time in front of filename for better sorting]
It is possible to use command DIR to get recursive listed all files in the specified folder and its subfolders with creation date/time.
The format of the date/time depends on Windows Region and Language settings.
Example output for F:\Temp\Test on my machine with English Windows 7 and region is configured to Germany on running the command line dir F:\Temp\Test\* /A-D /S /TC:
Volume in drive F is TEMP
Volume Serial Number is 1911-26A4
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
1 File(s) 465.950 bytes
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
1 File(s) 360.546 bytes
Total Files Listed:
2 File(s) 826.496 bytes
0 Dir(s) 58.279.460.864 bytes free
This output is filtered with findstr /R /C:"^ Directory of" /C:"^[0123][0123456789]" to get only lines starting with Directory of (note the space at begin) or with a number in range 00 to 39.
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
And this filtered output is processed by FOR loop and the commands executed by FOR.
#echo off
for /F "tokens=1-2*" %%A in ('dir "F:\Temp\Test\*" /A-D /S /TC ^| %SystemRoot%\System32\findstr.exe /R /C:"^ Directory of" /C:"^[0123][0123456789]" 2^>nul') do (
if "%%A %%B" == "Directory of" (
set "FilePath=%%C"
) else (
set "CreationDate=%%A"
set "CreationTime=%%B"
for /F "tokens=1*" %%I in ("%%C") do set "FileName=%%J"
call :RenameFile
)
)
goto :EOF
:RenameFile
set "NewName=%CreationDate:~-4%-%CreationDate:~3,2%-%CreationDate:~0,2%_%CreationTime:~0,2%-%CreationTime:~3,2%_%FileName%"
ren "%FilePath%\%FileName%" "%NewName%"
goto :EOF
It would be advisable to put command echo before command ren in last but one line to first verify the expected new file names.
ren "F:\Temp\Test\SimpleFile.ccl" "2017-09-25_17-26_SimpleFile.ccl"
ren "F:\Temp\Test\Test Folder\Test File.tmp" "2017-09-25_17-26_Test File.tmp"
Note: The batch file must be in a folder not processed by this batch file as otherwise the batch file itself would be renamed while running which breaks the processing of the batch file.
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.
call /?
dir /?
echo /?
for /?
goto /?
if /?
ren /?
set /?
By the way: WinRAR can add files into a RAR archive with creation and last access time in addition to last modification time and extract the files to a different directory with restoring also creation and last access time using SetFileTime function of Windows kernel.
currently I use Locale independent date. I use tokens from that for currrent date/time.
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem :: format it to YYYY-MM-DD_hh-mm-ss
set myDateTime=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%_%datetime:~8,2%-%datetime:~10,2%-%datetime:~12,2%
Thats not the problem.
To clarify:
The listing is also not the problem.
I loop throw all related files without a prob (except batch files and output dir and its sub tree ;).
My problem is:
I call robocopy for each file, then I rename the file to save the original creation date. My fear is that it makes problems (Multi-Threading?) for large files and for the number of calls (many thousend times)
Is batch execution really serialized? Is the process waiting for robocopy, that it has finished, before I try to rename file. Could I run into dead-locks for vry large files? I'll test it with some fake gigabyte-files.
Your suggestion, to use winrar sounds interesting.
If I could add all that files to a big archive (with structure) and at the end extract it to target dir... I'll try it ;)
If it doesn't work I will program it in java!
There I know what to do, thats my playground :D
I thought it would be easy to write a simple batch file, to do this for me, but it seems it's not as easy as I thought!
ThanX anyway
I've been experimenting with Xcopy on my flash drive, which as the reader most likely knows, is a way to transfer multiple file copies very efficiently. During my experimentation, i had a thought. The code i ran(which will be disclosed at the end of the comment) was set to copy files from my desktop, music, photos etc. However, on my desktop was a particularly large file for a game i frequent. When the program got to the games files, it took an extremely long time to copy the files, as the game ran a 3D environment, and i needed this code to run quickly and efficiently. So, my thought was:Is there a way to copy the name of a file(in this case, the name of the game, FTB), have the program copy the name of the file only, then create a text file on the flash drive where the code is being run, then overwrite the name of that document with the copied name?
Here is the code being run, and i am aware that it has some obvious problems, but its being worked on:
#echo off
:: variables/min
SET odrive=%odrive:~0,2%
set backupcmd=xcopy /s /c /d /e /h /i /r /y /EXCLUDE:MyExcludes.txt
%backupcmd% "%USERPROFILE%\Pictures" "%drive%\all\My pics"
%backupcmd% "%USERPROFILE%\Favorites" "%drive%\all\Favorites"
%backupcmd% "%USERPROFILE%\Videos" "%drive%\all\Vids"
%backupcmd% "%USERPROFILE%\Documents" "%drive%\all\Docs"
%backupcmd% "%USERPROFILE%\OneDrive" "%drive%\all\Onedrive"
%backupcmd% "%USERPROFILE%\Desktop" "%drive%\all\Desktop"
%backupcmd% "%USERPROFILE%\Network" "%drive%\all\Other devices"
copy "Bookmarks.bak" "all"
removedrive D: -L -H -A -W:1000
if you need any extra information, just ask.
add the large file to the myexcludes.txt file so it wont copy
just create a new file on your backup drive using something like the following (assuming your file is called mylargefilesname.ext)
echo mylargefilesname.ext > "%drive%\location\mylargefilesname.ext"
------ edit ------
To do this for all .exe files you can exclude *.exe and then use a loop.
for /f %%f in ('dir /b "%USERPROFILE%\Pictures\*.exe"') do echo %%f > "%drive%\all\My pics\%%~nxf"
this is looping over the results of dir /b "%USERPROFILE%\Pictures\*.exe"
for each line of the output it will echo the full file path to your new folder using the filename + extension of the file (thats what the nx part does)
I know this is resurrecting an old thread, but I've found this code all over the internet (it's been copied a lot) with no clear explanation of the nonsensical %odrive% initialization and the non-initialization of %drive%.
It doesn't work because they left out some code. Here's how to fix it:
Replace:
SET odrive=%odrive:~0,2%
With:
SET odrive=%CD%
SET drive=%odrive:~0,2%
The first line gets the current directory as %odrive% and the second line strips out the first two characters (e.g., C:) and assigns them to %drive%
Note the script assumes it's being run from the removable drive. So you could simply replace all instances of %drive% with . and it would work just as well.
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 have a good command over cmd commands, but this may require a variable or a loop which is where I fail in batch commands. Please help if you can!
-- Have about 100 subdirectories each has 1-20 HTML files in it. There are about 100 HTML files in the root directory too.
-- Need to replace all HTML files in the above directories with the same HTML source (copy over existing file and keep the name the same). Basically trying to replace all existing files with a redirect script to a new server for direct bookmarked people. We are running a plain webserver without access to server-side redirects so trying to do this just by renaming the files (locked down corp environment).
Seems pretty simple. I can't get it to work with wildcards by copying the same file over to replace. I only get the first file replaced, but the rest of the files will fail. Any one with any advice?
This should do it from the command prompt. Replace % with %% for use in a batch file.
for /r "c:\base\folder" %a in (*.html) do copy /y "d:\redirect.html" "%a"
Without knowing more precisely how you want to update the file content I suggest the following rough approach.
To re-create your example, I had to create some folders. Run this command to do that:
for /l %i in (1,1,20) do mkdir fold%i
I then used this script to create some example files:
#echo off
set number=0
for /d %%i in (c:\Logs\htmltest\*) do call :makefiles %%i
goto :EOF
:makefiles
set /a number+=1
touch %1\file%number%.txt
echo %number% >%1\file%number%.txt
I then used this script to append the text changed to the file. Not sure if that is what you wanted - probably you need something more sophisticated.
#echo off
set number=0
for /d %%i in (c:\Logs\htmltest\*) do #for %%f in ("%%i\*.txt") do call :changetext %%f
goto :EOF
:changetext
echo changing file contents to ^"changed^" for file: %1
echo changed>>%1