How to manipulate parameters like #path with ForFiles - batch-file

I'm using forfiles in a batch-file to find all files changed within the last day and save them to an archive directory.
The script works perfectly to pull files from one directory to another, however it does not do the desired function when there are sub directories.
e.g. I have a Source location and an Archive directory. In the source directory there is the following structure:
C:\Temp\Source\test1.txt
C:\Temp\Source\Folder\test2.txt
The Archive directory is simply the below location with no files/sub folders in it:
C:\Temp\Archive
My current use of ForFiles picks up both test1.txt and test2.txt and dumps them into the Archive directory, which is an undesired result:
C:\Temp\Archive\test1.txt
C:\Temp\Archive\test2.txt
What I want to do is preserve the folder structure and get this result:
C:\Temp\Archive\test1.txt
C:\Temp\Archive\Folder\test2.txt
This is the code I'm currently using to achieve the undesired result is:
FORFILES /S /p %source_dir% /m *.* /d +%datedsub% /c "cmd /c copy #path %archive_dir%"
%datesub% is just my variable to decide what date to copy from.
I have noted that I could achieve this by using the #relpath parameter, removing the quotes and .\, then appending it to the %archive_dir% so that I'm specifying the entire destination path rather than just the Archive location.
My problem is that I do not know how to manipulate the # variables whilst within a ForFiles command.

Related

Using FORFILES to move files to Archive folder, tilde in directory name

I am attempting to use FORFILES for the purposes of archiving files and I have all of the information from the help and examples that work except for this one piece. In my network path, someone in their infinite wisdom used the tilde (~) character as the directory name, ie y:\dept\deptname\~~~ DOWNTIME FOLDER ~~~\data\ and I have another folder below the \data\ folder called archive. I am trying to move all files in \data\ older than 30 days to the archive folder. As long as I move my command line to the directory in the batch file I am creating, I don't have to reference the directory completely to get it to give me back the #path or #relpath in an echo statement but I cannot reference the full directory path to "move" the files to the \archive path in the second half of the FORFILES statement. Any suggestions on how to 'replace' the tilde in the directory path?
Here is my full statement:
FORFILES /D -30 /C "cmd /c if #isdir==FALSE move #file y:\dept\deptname\~~~ DOWNTIME FOLDER ~~~\data\archive"
This just gives back an error Access is denied, but yet I have access to this network location for both the directory \data\ and subdirectories below.

bcp append files using command

I cannot append the files together using bcp command. I am getting one file and changing the name of it to todays date, every half hour a file comes in which needs appending to the renamed txt which has the date stamp in the file. once appended that file is move to another folder.
This occurs everyday moving the old txt into another folder and starting the process again. I can't manage to get this into one command script so I can put it into two batch files.
The first renames the file and clears out any old files from two locations, one is yesterdays file and the other is an archive folder for anything over 100 days (days doesn't matter as I am in testing at the moment):
rename C:\Testing\WithRCD\data_list201 CM_Exclusions_%date:~-4,4%-%date:~-7,2%-%date:~-10,2%.txt
forfiles /p c:\Testing\WithRCD\ /m *.txt /d -1 /c "cmd /c move #FILE c:\Testing\WithRCD\Archive\"
forfiles /p "c:\Testing\WithRCD\Archive\" /m *.* /d -100 /c "cmd /c Del c:\Testing\WithRCD\Archive\"
This seems to work but when trying to append the file together they will not, I am trying to use the following code:
copy /Y/V/DS data_list201+CM_Exclusions_%date:~-4,4%-%date:~-7,2%-%date:~-10,2%.txt
or even
copy data_list201+CM_Exclusions_%date:~-4,4%-%date:~-7,2%-%date:~-10,2%.txt TempFile.txt
DEL CM_Exclusions_%date:~-4,4%-%date:~-7,2%-%date:~-10,2%.txt
REN TempFile.txt CM_Exclusions_%date:~-4,4%-%date:~-7,2%-%date:~-10,2%.txt
but nothing I have tried is working.

Batch script command

I am a rookie at programming.
I have created a batch script to move files from one location to other based on date.
I want to move all files expect the files having modification date 3 days lesser than the current date.Also I want to log the files which has been moved in a new text document.
I am able to move the files but not able to log the moved files.
Command which i used is
forfiles /p C:\Users\Desktop\batchtest\ /s /m . /d -3 /c "cmd /c move #FILE \"C:\Users\Desktop\nov""
What i need is to create a textfile which shows the files moved by the above command.Could someone help me on this?
This is not same to Just deleting the file based on the date I suppose.
You could redirect all command output in to a file, like so:
forfiles /p C:\Users\\Desktop\batchtest\ /s /m . /d -3 /c "cmd /c move #FILE \"C:\Users\Desktop\nov"">log.txt
Notice the ">log.txt". That will redirect all non-error output into the provided file. It will create it if it isn't there. If you want to redirect errors, too, put a 2>log.txt >log.txt at the end instead. Source

How to delete files matching a certain pattern in their name?

I'm creating a batch file that deletes all Rar$DIa0.??? folders in the %TEMP% directory.
Is this possible, and how to do it?
The ??? is three randomized numbers. And that's where I have trouble with - deleting all folders that have Rar$DIa0. in the name.
for /d is designed for just this type of use. Something like this should work (remove one of the % if you're testing from the command line):
for /d %%i in ("%TEMP%\Rar$DIa0.???") do rd "%TEMP%\%%i"
The /d makes it work on directory names instead of file names.
If you want to make it easier on yourself, change to the %TEMP% folder first:
pushdir
cd /d %TEMP%
for /d %%i in ("Rar$DIa0.???") do rd "%%i"
The ??? makes it only act on folders that have three letters after a .. If your folders don't have just a three letter extension, change .??? to .*. If you've got a typo, and there is no actual . in the foldername, just remove it and use Rar$DIa0??? or Rar$DIa0*
You may want to test it first by changing rd to echo to make sure you get the folders you want before actually deleting them.
For more information about for (pun intended) type for /? from a command prompt.
The command line to use in a batch file for this task is:
#for /D %%I in ("%TEMP%\Rar$DIa0.*") do #rd /Q /S "%%I"
Command FOR with option /D searches in folder defined by environment variable TEMP for subfolders with folder name starting with Rar$DIa0. not having hidden or system attribute set.
The loop variable I holds for each found subfolder matching this folder pattern the name of found folder with full path without double quotes although the path to temp folder very often contains 1 or more spaces.
For that reason just the command RD with the parameters /Q for quiet execution and /S for deleting also all subfolders in the specified folder must be called with referencing the current value of loop variable I enclosed in double quotes.
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.
for /?
rd /?
By the way: WinRAR deletes the temporary folders usually automatically, except a file is opened from within an archive for viewing/modifying it in another application and WinRAR is closed before the other application is exited with the opened file. In this case WinRAR can't delete the temporary folder with temporarily extracted file because the file is still opened in another application. Of course also command RD can't delete the temporary folder if this folder is still the current directory of another application or a file in this folder is still opened by another application with a read/write access lock.

xcopy does not create directory structure

I have a strange problem with xcopy in Windows XP Professional. I don't know if its a stupid question as I am specifying only a file as the source, so should I even expect any other behavior ? This is it:
I am using xcopy <src> <dest> /s/y.
<src>=C:\sourcefolder\a\b\c\d\something.java and
<dest>=C:\destinationfolder.
Now xcopy copies the file but does not create the directory structure \a\b\c\d\ inside C:\destinationfolder .
what I want is C:\destinationfolder\a\b\c\d\something.java and
what I get is C:\destinationfolder\something.java
I have tried to run it in destination folder C:\destinationfolder by specifying a . for target folder
Tried it without any target in above
There is a script I have which calls xcopy iteratively so I am left with C:\destinationfolder\many java files without any directory structure.
A. Yes I have done xcopy /? to see all options
B. /T also does not create any empty directory structure
C. I can not go to source folder a\b\c\d\ and run xcopy . <dest>
UPDATE
I removed my previous answer on using ROBOCOPY. I believe the following will do what you want using XCOPY.
Assuming your folder structure is like this:
SOURCE = C:\MyJavaStuff\A\B\C\D\something.java
DEST = C:\MyDestination
Run XCOPY like this:
XCOPY C:\MyJavaStuff\something*.java C:\MyDestination /S /E
Note the * in something*.java.
The problem is that you are specifying which file to copy in the source. xcopy won't create the folder structure in this case. However, if you change your call to xcopy to
xcopy *.java C:\myfolder /s/y
it will copy the .java files and the folder structure as well. You need to specify a wildcard for this call to work as you want. If you want only to copy specific files, you will have to adjust the call to xopy, e.g.:
xcopy something.jav* C:\myfolder /s/y
Edit
You say that you get the list of files to copy from another command. If you can output this list of files in a text file, you could do the following:
FOR /F "tokens=* delims=," %F in (d:\test\list.txt) DO xcopy src\%~nxF* .\dest /S /Y
What this command does is read a text file ("d:\test\list.txt" in this case), read every line, and for each file, run xcopy, adding a wildcard at the end of the file name to make sure it creates the folder structure.
I'm assuming here that:
You can get the list of files in a text file, with only the file names (and optinally the paths)
You know the source folder ("C:\sourcefolder" in your example, the folder structure "a\b\c\d" does not need to be known) and can use it in the FOR command.
You can also use the following form:
FOR /F "tokens=* delims=," %F in ('cmd') DO xcopy src\%~nxF* .\dest /S /Y
where cmd needs to be replace with the command you use to generate your list of files to copy.
Note that if you use this FOR command in a batch file, you need to replace %F with %%F (and %~nxF* with %%~nxF*).
I had a look at the xcopy switches and you can copy the directory structure with /T, although that doesn't copy empty directories you can override this with /E. So your command would look like this:
xcopy C:\sourcefolder\a\b\c\d\something.java C:\destinationfolder /T /E /S /Y
Hope this helps!
In order to get C:\destinationfolder\a\b\c\d\something.java XCOPY needs to know how much of C:\sourcefolder\a\b\c\d\something.java to duplicate.
You can use:
C:
cd \sourcefolder
XCOPY something.java* C:\destinationfolder\ /S
Just be aware that this may have the side effect of also copying C:\sourcefolder\oops\something.java to C:\destinationfolder\oops\something.java as well as any other matches for something*.java under C:\sourcefolder\.
It seems to me that xcopy is typically used for copying directory trees, not single files (though it can work). And, xcopy will recreate the directory structure under the source folder in the target folder. If xcopy is given the /i switch, the target folder is assumed to be a directory. It will be created if it does not exist, even if there are multiple parents that need to be created.
You have C:\MyJavaStuff\A\B\C\D\something.java - that is your source. You want to end up with something.java not in C:\destinationfolder, but in C:\destinationfolder\A\B\C\D - so that is your target. You don't even have C:\destinationfolder. That is OK, with /i the entire path will be created.
xcopy /i c:\MyJavaStuff\A\B\C\D\something.java C:\destinationfolder\A\B\C\D
If something.java were the only file under C:\MyJavaStuff, you could also use
xcopy /sei c:\MyJavaStuff C:\destinationfolder
That would recreate the entire tree structure, copying your file. But if there are other files (and folders) under MyJavaStuff they would also be copied.
I have written a very similar batch file using xcopy. Perhaps what I did will help you.
This is the command I used:
xcopy "c:\Data Files\Dave's Data\*.*" "m:\Dave's Data" /R/D /E/H
In this case, Dave's Data on the source contains an entire directory tree containing at least 50,000 files & exceeding 75GB data. It runs perfectly on Windows XP
I found /T was unnecessary as the directory tree is copied. I also found /S was unnecessary as /E copied directories & sub-directories including empty ones. I included /R to copy & overwrite read only files on the destination. /H copied hidden directories. /D copied only newer files. I use this as a daily backup tool for my data.
The only problem I have is while this command will work on Windows 7 the first time, it will not work on subsequent runs when the destination directory tree exists. I suspect this is due to a privilege issue as the xcopy command will work on subsequent runs on Windows 7 within a cmd.exe window.

Resources