I'm working with the forfiles command
I am attempting to get a list of files newer than X days ago.
When I use the /D +X command I get a not files found error:
forfiles /P %filename% /D +3
However if I use a date it works fine:
forfiles /P %filename% /D +06/29/2016
Am I missing something on the +X formatting? It seems like it is adding 3 days to the current date and then looking for files newer than that.
Or is there a simpler way to increment the date than I'm aware of. Only work with Batch once in a while
I don't want to use vbs, and I would rather not have a set of code longer than the rest of my script just to get the date, there should be a simpler way.
Related
I want to be able to create a batch files that copies files by date only up to 3 or 4 days but use the %edate% %user%\ syntax instead of specifying a date. Here is what I have so far:
XCOPY %user%\folder_1 %edate% %user%\folder_2.
I am unable to download any 3 party software. I can only use the .bat format.
The comment suggestion to use forfiles is a good one, but I note the question has remained open. Perhaps more details are required.
If the questioner has a system more recent than XP (and I assume so, as XP and previous are now deprecated) the ROBOCOPY also has appropriate options. I'll give examples of both for files greater than 4 days old.
Using forfiles:
FORFILES -P %user%\folder_1 /D - 4 /C "CMD /C XCOPY #file %user\folder_2"
Using ROBOCOPY:
ROBOCOPY %user%\folder_1 %user%\folder_2 /MINAGE:4
I hope that is sufficient detail....
I'm a bit of a newbie with batch files, but am looking for a script to delete .txt log files that are older than 30 days... (FWIW, I am on XP SP3...)
I tried to follow the example found here, (including downloading the forfiles.exe from here) and ended up with this:
forfiles -p"D:\SQL Database Back Ups\Update_FmlaManagement_Log" -s -m *.txt -d-30 -c "cmd /c del #FILE"
But I get this error:
Error path not found (3rd argument) line 545
I did a lot of googling, but can't seem to figure out what this error is talking about. Somebody suggested using forfiles.exe in order to get the #variables to work, but I tried that (along with the full forfiles path), and nothing seems to be working...
Can someone at least point me in the correct direction as to what this error message is telling me?
Just to see whether I could, I cobbled a little sumn sumn together to delete files older than 30 days old without using forfiles. Make sure the pushd line is set to go to the appropriate directory. I got the 2592000 by subtracting 01/01/2013 from 01/31/2013.
#echo off
setlocal enabledelayedexpansion
pushd "D:\SQL Database Back Ups\Update_FmlaManagement_Log"
set today=%date:~-10%
call :toEpoch %today%
set /a thirtyDaysAgo=%epoch% - 2592000
for /f "tokens=1,5*" %%I in ('dir /o:d *.txt ^| findstr "txt$"') do (
call :toEpoch %%I
if "%%K"=="" (set file=%%J) else (set file=%%J %%K)
if /i %thirtyDaysAgo% GTR !epoch! del /q "!file!"
)
popd
goto :EOF
:toEpoch date
echo wscript.echo datediff("s", "01/01/1970 00:00:00", "%1")>epoch.vbs
for /f %%x in ('cscript /nologo epoch.vbs') do set epoch=%%x
del /q epoch.vbs
goto :EOF
(VBscript borrowed from Cameron Oakenleaf.)
Admittedly, this won't work obsessively accurately. For instance, if a log file was last modified at noon 30 days ago and you're running this at 8:00 am, the file will probably be deleted even though it still has another 4 hours to go to reach 30 days old. And it's probably not nearly as efficient as forfiles.exe.
*shrug* It was a road less traveled and I traveled it.
EDIT: HerbCSO has another, probably better implementation that makes mine look like a Rube Goldberg-ian solution.
#file is only the File name. It does not include the path. If your batch file is not being executed within your path it will not see the file to delete it because you are in a different working directory.
I can't believe that the error comes from your sample line.
My forfiles (Win7) throws an error for the missing space between -p and the path.
And the text of the error message isn't normal for batch commands.
I don't know any batch command that tells you the line where an error occours, nor which parameter is wrong.
So I believe you got the error message from a completly different source.
Or you have a second forfiles command that do some totally other thing.
Or do you named one of your tests forfiles.bat?
Well, I'm not positive, but it seems the issue might have been a bad forfiles.exe from Microsoft's FTP server. I ended up downloading a second forfiles.exe (for Windows Server 2003) from this guy's site (direct download).
After replacing the original exe in C:\WINDOWS\system32 and getting rid of the copy in my downloads folder, I changed the syntax a little from the dashes to forward slashes as follows:
forfiles /p "D:\SQL Database Back Ups\Update_FmlaManagement_Log" /s /m *.txt /d -30 /c "cmd /c del #FILE"
and this worked perfectly first try!
So I guess the answer is, don't download forfile.exe from Microsoft's FTP server? :P
EDIT:
I would be very interested to know if other people have successfully used Microsoft's .exe in the link above? Otherwise maybe it's just something with my particular setup...
So I've got a batch file that backs up a folder to my Google Drive directory, like so:
C:\Program Files\WinRAR\rar.exe a -r "D:\Google Drive\Saves Backup\%DATE%.rar" "D:\Documents\My Games\"
This makes a file called 30-Sep-12.rar (being run today) in the appropriate folder.
However, my question is this: Is there some way to go through said folder (D:\Google Drive\Saves Backup) and delete backups that are more than a week old, as determined by the filename?
Why must you use the date embedded within the file name? The last modified date should be the same as the date embedded in the file name as long as the backup has not been modified since it was created.
FORFILES is one of the few Windows utilities that conveniently works with date arithmetic. Type FORFILES /? from the command line to get help on its usage.
forfiles /p "D:\Google Drive\Saves Backup" /m "*.rar" /d -7 /c "cmd /c del #path"
If you have a risk that someone could modify a backup, thus changing the last modified date, then the above will not work. Parsing and comparing dates is a pain in batch. You would be better off using VBScript.
I'm trying to create a batch script that will delete all sub directories which are older than 30 days.
I'm really new to batch scripting so I'm just hoping that someone can help me out on this.
I was able to find a script that delete all sub directories in specified location.
#for /f "tokens=*" %%a in ('dir /s /b "C:/temp/test" 2^>NUL') do rd /s /q "%%a"
Can someone tweak this script so it deletes only directories which are 30 days old?
I think FORFILES is going to do it...
FORFILES -D 30 will iterate all files last modified over 30 days ago
So, something like...
FORFILES /S /D -30 /C "cmd /c IF #isdir == TRUE rd #path"
Should (untested) recursively remove all folders older than 30 days :)
Btw - Check out http://ss64.com/nt/ for more command line goodness
This is working fine for me:
Posted by Matt Roberts --> FORFILES /S /D -30 /C "cmd /c IF #isdir == TRUE rd #path"
Be careful when you start the ".bat" file with "Run as administrator", it's not using the current location of the file it takes this location --> "C:\Windows\system32"
For savety reasons add the /P "C:\temp"
FORFILES /P C:\temp /S /D -30 /C "cmd /c IF #isdir == TRUE rd #path"
Assuming you are restricted to batch files... check this - but if you can use VBScript, I think you can do a bit better.
Now that you have clarified your real problem, please understand that if you meant to use System.exec() you will have to contend with plenty of drawbacks.
Alternatively if you really want to use JNDI (you mention "native" but don't make clear what you mean) maybe this will be of help: http://mindprod.com/products1.html#FILETIMES
Do you have powershell on your system?
dir | ? { $_.LastWriteTime -lt [DateTime]::Now.AddDays(-30) } | % { rm $_.FullName }
I know this is an older topic; however, I was recently looking to do this and was able to by building off of what Matt Roberts suggested. I used the following FORFILES syntax:
FORFILES /P \path\to\dir /S /C "cmd /c IF #isdir == TRUE rmdir /S #path /Q" -D -30
You will need to replace \path\to\dir with the path (including drive letter) to the directory (/P) you want to run this on. This will then recursively (/S) search through the directory and run (/C) rmdir (again recursively). Without /Q you are asked if you want to delete each dir/file so if you are planning on running this silently in a script you will need to have it. You can change the amount of days (-D) by changing -30 to something else.
I then used Task Scheduler to automate this once every week (confirmed working). To make sure it works, set the task with 'run with highest privileges'
Note: This setup will irrevocably delete the files. They will not appear in your recycle bin. So once they are gone they're gone (unless you have backups).
You might want to consider using Windows Script Host, in which you could run a VBScript to do just that. Think of it like a batch file with more flexibility and power.
See http://www.computing.net/answers/programming/wsh-delete-files-in-folder-by-date/16255.html
This is not going to be a simple tweak. As it stands, there is no easy way (that I know of) to do the date-diff operation in the cmd interpreter.
First you'll have to parse the current date:
C:\>date /T
Thu 08/05/2010
Once you have the day, month, year, you have to get the date for each item in the directory listing, which you can do by removing the /b param in the dir command and modifying the tokens line to give you tokens 1 and 4, i.e. tokens=1,4, and then doing the date math yourself, which will be a pain because you have to handle different lenght months, and December -> January transitions (new years), etc, and you're almost certain to get it wrong.
Also add the /ad param to get just directories.
I would recommend using PowerShell or some other scripting technology that gives you the tools you need to manipulate dates.
I just want to know:
How can I delete 'log.txt' if the last modification was not today?
With a batch file.
I'm just talking here about 1 FILE!
PowerShell must replace batch.
if ((dir log.txt).LastWriteTime -lt [datetime]::today) { del log.txt }
You can use forfiles:
forfiles /D -1 /M log.txt /C "cmd /c del #file"
Unfortunately you can't do this in a robust and general way (*).
Powershell, Cygwin, Unix Tools are perfectly good solutions if you can be sure they'll be installed on the target machine.
I wrote a little utility program that takes a path with wildcards and number of days and deletes all files matching the path that are older than the specified number of days. In my environment this was more convenient than installing a 3rd party package.
(*)
The following will work for your specific case (modification date not today) as long as the short date format in your regional settings includes the century (i.e. is 10 characters long). But it doesn't generalize for N days, and I don't like relying on the computer's regional settings for this kind of thing:
for %%i in (log.txt) do SET FILETIME=%%~ti
IF NOT "%FILETIME:~0,10%" == "%DATE%" DEL /f log.txt
Batch makes something that simple very complicated.
If you can use Cygwin, or install Unix Tools, consider doing something like this:
find log.txt -mtime +1 -exec rm {} \;
UPDATE
Found something that might be useful to you using pure batch. You should be able to modify that and adapt it to suit your needs.
For what its worth, you could use either jscript or vbscript. Both of these scripting languages have been installed on MS platforms since the mid 90's