Batch file to delete files older than N hours or minutes - batch-file

I see this - Batch file to delete files older than N days
But how can I delete files older than N hours or minutes?
Thanks.

Neither of the solutions here worked for me. They are very innovative solutions, and the first one (.net/FileTimeFilerJS.bat [sic]) actually worked once for me. When I tried to call it on another folder, however, it simply crashed. I tried the second one (jscript/FileTimeFilterJs.bat), but it did not successfully delete all files older than one hour.
My solution requires an executable, but I found it was the best solution for me.
I downloaded FindUtils from GnuWin32, and extracted 3 files (you have to download the two zips below): libintl3.dll, libiconv2.dll, and find.exe (combined they are about 1MB in size). I rename find.exe to gnu_find.exe just to avoid the Windows FIND command.
Then, you can run the beautiful GNU command (below command is for all zip files older than 120 minutes in folder specified by environment variable %fldr%):
gnu_find %fldr% -name *[.:]zip -type f -mmin +120 -delete
Instead of *.zip, I use *[.:]zip, because Windows 7+ will expand the *.zip before find can use it.
Find Utils bin
Find Utils deps

Its challenging to do this (independent of time date settings) even with WSH\Jscript\VBscript as WSH does not return date object when you request the date/time properties of a file ,but a string that depends on time settings (wmi could be used but this will hit the performance).
I suppose you have installed .net framework which make the task far more easier.
Here's a hybrid tool that should work in your case. You can save it with whatever name you want. Here's how to use it (its called FileDateFilterJS.bat in this example):
#echo off
for /f "tokens=* delims=" %%# in ('FileDateFilterJS.bat "." -hh -5') do (
echo deleting "%%~f#"
echo del /q /f "%%~f#"
)
pause
Where the hours are 5 - -hh -5 and directory is current - "." .You can remove the echo before del command.
This script took me far more time than I've expected (despite I've researched the topic and has some parts ready) and is no so heavy tested so probably is still not buggy-free.And I suppose the help message and options could be improved.

#echo off
cd /d "your file path"
:: delete files 3 hours ago. If you want other condition, refer https://www.w3schools.com/asp/func_dateadd.asp
echo wscript.echo dateadd("h",-3,now())>GetOldDate.vbs
for /f "tokens=1,2 delims= " %%i in ('cscript /nologo GetOldDate.vbs') do (
set d=%%i
set t=%%j
)
echo "%d%"
echo "%t%"
for /f "tokens=1,2,3 delims=/" %%a in ("%d%") do (
set y=%%a
set m=%%b
set d=%%c
)
for /f "tokens=1,2,3 delims=:" %%a in ("%t%") do (
set h=%%a
set mm=%%b
set s=%%c
)
if %m% LSS 10 set m=0%m%
if %d% LSS 10 set d=0%d%
if %h% LSS 10 set h=0%h%
if %mm% LSS 10 set mm=0%mm%
set OldDate=%y%/%m%/%d% %h%:%mm%
echo "%OldDate%"
del GetOldDate.vbs
for %%a in (*) do (
if "%%~ta" lss "%OldDate%" (
echo %%a
echo "%%~ta"
del %%a
)
)

Deleting files:
#echo off
echo >%temp%\temp.vbs for each File In CreateObject("Scripting.FileSystemObject").GetFolder("[path_file]").Files
echo >>%temp%\temp.vbs If DateDiff("n",File.DateCreated,Now) ^> 30 Then File.Deletee
echo >>%temp%\temp.vbs next
cscript /nologo %temp%\temp.vbs
Exit /b
Deleting folders:
#echo off
echo >%temp%\temp.vbs for each Folder In CreateObject("Scripting.FileSystemObject").GetFolder("[Path_folder]").subFolders
echo >>%temp%\temp.vbs If DateDiff("n",Folder.DateCreated,Now) ^> 30 Then Folder.Delete
echo >>%temp%\temp.vbs next
cscript /nologo %temp%\temp.vbs
Exit /b
To vary the time difference, we need to substitute in DateDiff("n",[Folder or File].DateCreated,Now) ^> 30, the condition (in this case 30 minutes).
.DateCreated can be changed by: .DateLastAccessed or .DateLastModified.
Time difference: "yyyy" Year, "m" Month, "d" Day, "h" Hour, "n" Minute, "s" Seconds.
["Path_file o Path_folder"] has to be sustituded for the target file or folder.

Here's another script that relies only on WSH/JSCRIPT and almost the same interface (and does not require .net installed).To show files older than 5 hours use:
FileTimeFilterJS.bat "." -hh -5 -filetime modified

Related

Batch/CMD Error "The system cannot find the file specified"

I'm trying to write a batch/cmd file that will rename directories when it finds " - " that is SpaceDashSpace. I thought I had everything I needed by outputting things via Echo and not actually renaming them. Next I tested it on a few directories and it worked perfectly.
When I tried to move it to a networked folder/sub folder I found I needed the PushD command. Again all is well if I run it in a specific directory.
Path information would look something like:
\\MyNetworkStorage\TopLevelFolder\Music
Followed by:
Artist1
Artist1 - Album1
Artist1 - Album2
Artist1 - Album3
Artist2
Artist2 - Album1
Artist2 - Album2
You get the idea.
If I kick the batch file off in either:
\MyNetworkStorate\TopLevelFolder\Music\Artist1 or
\MyNetworkStorate\TopLevelFolder\MusicArtist2
all is good. If I try to do it from one level up, that is:
\MyNetworkStorate\TopLevelFolder\Music
I get the following error for every single directory.:
"The system cannot find the file specified"
Googling tells me the path might be to long and I've followed instructions to
Local Computer Policy > Computer Configuration > Administrative
Templates > System > Filesystem
Double click the Enable Win32 Long
paths option and enable it
Another suggestion was when running my .cmd file on the local machine to preface it with:
cmd.exe /c MyCmdFile.cmd
Nothing I've searched for has fixed my problem.
I'm new to batch files so perhaps the problem is actually in what I've cobbled together the last 1.5 days. At this point I wish I wrote a C# program for it. I thought this would be simple. Any suggestings?
Again if I start it in any specific Artist's directory it will rename all the sub-directories removing the "Artists Name - " portion and leave just the album name as I want it to. When I move up to the directory that contains all the artists, it fails. I'm changing this on line that starts with "PUSHD" of the command file.
#Echo Off
setlocal EnableDelayedExpansion
PUSHD \\MyNetwork\Music\HighRez <<<---This fails
PUSHD \\MyNetwork\Music\HighRez\Any Artist I pick <<<---This works for all sub directories
:: If this fails then exit
If %errorlevel% NEQ 0 goto:eof
:: other commands...
FOR /D /r %%G in ("* - *") DO (
SET DirName=%%~nxG
set "NewName=!DirName:* - =!"
Echo Renaming from "!DirName!" To "!NewName!"
REM ***Remove REM from line below to actually rename once you are happy with results
ren "!DirName!" "!NewName!"
)
popd
This is what ended up working for anyone who might need something similar. It was the combination of using %%G along with quotes around it as in:
ren "%%G" "!NewName!"
In place of the original variable "!DirName!"
Working example, finally ;-)
#Echo Off
setlocal EnableDelayedExpansion
PUSHD \\NASBoxOnNetwork\Music\HighRez
:: If this fails then exit
If %errorlevel% NEQ 0 goto:eof
:: other commands...
FOR /D /r %%G in ("* - *") DO (
SET DirName=%%~nxG
set "NewName=!DirName:* - =!"
Echo Renaming from "%%G" To !NewName!
REM ***Remove REM from line below to actually rename once you are happy with results
ren "%%G" "!NewName!"
)
popd

Batch For loop.. wildcards to determine length of searched files?

I'm stuck on a piece of code that I mainly didn't write myself. I'm looking for a code that runs through all files with extension .dwg, and start with K_E , and have length 9. instinctively I used wildcards, but that doesn't work..
K_E??????.dwg would do the trick in my head..but doesn't.
the reason I need this length, is that in deeper folders there are
K_E??????xx.dwg and other files.
The other files in subfolders can have a range of other names, the general idea is that I only want files that are exactly named K_E[insert 6numbershere].dwg Either that, or the limit of folders depth = 2. I also tried the wildcard in the folder names to allow the code to look in only 2 deep folders for K_E*.dwg files, but that also didn't work. something like C:\Users\b00m49\Desktop\LSPTEST**\K_E*.dwg could also work..
the code is supposed to open the drawings, apply a script, and move on to the next file.
this is what I'm working with so far.
for /r "C:\Users\b00m49\Desktop\LSPTEST" %%a in (K_E*.dwg) do ( start /wait "C:\Program Files\Autodesk\Autocad 2013\acad.exe" "%%a" /b "C:\Users\b00m49\Desktop\LSPTEST\expSQM.scr")
So you just want to exclude files containing backup in their names? This should work:
#echo off
setlocal enabledelayedexpansion
for /r "C:\Users\b00m49\Desktop\LSPTEST" %%a in (K_E*.dwg) do (
set filename=%%a
if "!filename:backup=!"=="!filename!" (
rem start /wait "C:\Program Files\Autodesk\Autocad 2013\acad.exe" "%%a" /b "C:\Users\b00m49\Desktop\LSPTEST\expSQM.scr"
)
)
pause
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=C:\Users\b00m49\Desktop\LSPTEST"
SET "sourcedir=U:\sourcedir"
for /r "%sourcedir%" %%a in (K_E*.dwg) do (
FOR /f "tokens=1,6delims=\" %%m IN ("%%a") DO (
REM %%n contain dirname or filename or empty
REM %%n is only empty for 0, 1 or 2 levels down.
IF "%%n"=="" (
SET "name=%%~na"
IF "!name:~9!"=="" IF "!name:~8!" neq "" (
REM the name is not longer than 9 characters, but IS longer than 8
ECHO(start /wait "C:\Program Files\Autodesk\Autocad 2013\acad.exe" "%%a" /b "C:\Users\b00m49\Desktop\LSPTEST\expSQM.scr")
)
)
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances. I used a test directory.
The required START commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(START to START to actually start the processes.
I'm not sure what you mean by "two levels down" - I've assumed the target directory +two levels. Since your actual dirctory has 3 more levels than my test directory, you'd probably need to change 1,6 to 1,9
Simply use the tokenising feature to ensure that there are no more than ? levels of directory, where the drivename and filename count as levels. Ignore the file if there are.
Then get the name - we know the first 3 characters are K_E but we want exactly 6 characters after, so see whether there are characters 10+ and if there are not, make sure character 9 exists (characters count from 0) and if both of these conditions are valid then it must be K_E*6characters*
Could ensure that all 6 characters are numeric if required, but not actually specified.
BTW - to add information, please edit it into your question so people don't need to chase all over the thread.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\Users\b00m49\Desktop\LSPTEST"
for /r "%sourcedir%" %%a in (K_E*.dwg) do (
FOR /f "tokens=1,9delims=\" %%m IN ("%%a") DO (
REM %%n contain dirname or filename or empty
REM %%n is only empty for 0, 1 or 2 levels down.
IF "%%n"=="" (
SET "name=%%~na"
IF "!name:~9!"=="" IF "!name:~8!" neq "" (
REM the name is not longer than 9 characters, but IS longer than 8
ECHO(start /wait "" "C:\Program Files\Autodesk\Autocad 2013\acad.exe" "%%a" /b "C:\Users\b00m49\Desktop\LSPTEST\expSQM.scr")
)
)
)
)
pause
GOTO :EOF
This worked for me.
Notes:
The pause line should stop the procedure after it displays the command to be executed.
You would need to change U: to C: in the setting of sourcedir to have it process your c: drive.
You would need to change ECHO(start to start in order to actually execute the autocad processing. This technique (echoing the command) is used to show the command in order to have it verified. Note I've also deliberately inserted a pair of rabbit's-ears ("") because the first quoted argument to start is taken as the window-title.

Batch to pattern matching in a loop

I am trying to loop through a file which contains few names and search the same with two patterns in another file and echo some statements.
Like I have two files :
1.Installers.txt
2.Progress.txt
Installers.txt
abc.jar
def.jar
tef.jar
....
....
Progress.txt
abc.jar deployment started
abc.jar deployed successfully
def.jar deployment started
So my requirement is to read the Installers.txt file one line at a time and search for the 2 patterns "abc.jar deployment started" and "abc.jar deployed successfully" and report successful or else if both patterns are yet to be found to show as still in progress.
I have tried writing below but its failing at many things while doing pattern and the logic also does not look good. can someone help here.
for /F "usebackq delims=" %%a in ("Installer.txt") do (
set /A i+=1
call echo installing %%i%% : %%a
:NOTVALID
findstr /I "%%k\ in\ progress" %1%\progress.txt
If errorlevel 1 (
echo "installation still in progress.."
PING 127.0.0.1 -n 1 >NUL 2>&1 || PING ::1 -n 1 >NUL 2>&1
goto NOTVALID
) else (
set /A i+=1
echo "installation completed.."
call set array[%%i%%]=%%a
call set n=%%i%%
)
Try the below code which suite your requirement :
cls
#echo off
for /f %%g in (Installers.txt) do type Progress.txt|findstr "%%g" || echo %%g is Yet to start , still in progress
Above code will read a single line from installer and then search for that string in file Progress.txt and then print the output if it is found or not.

How can I append pictures which is not exist on folder?

I want to write .bat file,
I have two folders which names are A and B.
I have pictures on A , and I want to transfer them from A to B in every 10 minutes,
But I want to transfer the last 20 pictures. Pictures names are 1.jpg 2.jpg ,,,,90.jpg
How can I do that? Is it possible?
thanks
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=c:\destdir"
SET /a numbertomove=20
FOR /f "tokens=1*delims=:" %%a IN (
'dir /b /a-d /o-d "%sourcedir%\*.jpg"^|findstr /n "."'
) DO (
IF %%a leq %numbertomove% ECHO MOVE "%sourcedir%\%%b" "%destdir%\"
)
GOTO :EOF
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
Edited to remove self-scheduling.
to move the files you can use:
for /l %%i in (71,1,90) do move a\%%i.jpg b\%%i.jpg
For scheduling a task to run every 10 minutes see schtasks /create /?.
There are a lot of options, collect them to your needs.
It's a bit confusing to get the right syntax if you do it the first time, so you may have to ask a new question if you know, which options you want to use.
(NOTE: to use the forconstruct on commandline (not in batch) use single% instead of %%)

Concerning batch games, find and replace a string

I have made a character file in which my game pulls data and variables from. Looks like so:
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
Final Fantasy reference anyone...? Anyway, when the character levels up, I need a batch script to find the string "playerHP= 100". playerHP is set as a variable within the script. Basically, it takes the current health, and multiplies it by 120%, increasing the number. How do I echo the result of that math to replace the current number?
For example if that didn't make any sense, I have 100 health. I level up, thus increasing my health stat by 120%, so now I have 120 health. I would want to find the string "playerHP= 100" and replace it with "playerHP= 120".
If it can be avoided I don't want to download any other commands (I've seen sed a few times). Thanks much
EDIT: Instead of searching for the string and replacing I took jeb's advice and just deleted the file and re-echoed all of the data. It ended up looking like this:
set /a LeveledUpPlayerHP=(%ppHP%* 12) / (10)
set /a LeveledUpPlayerSPD=(%ppSPD%* 12) / (10)
set /a LeveledUpPlayerATK=(%ppATK%* 12) / (10)
set /a LeveledUpPlayerDEF=(%ppDEF%* 12) / (10)
echo Updating stats...
del "C:\Users\%USERNAME%\Desktop\CMDRPG\player\playerData.dll
ping 1.1.1.1 -n 1 -w 500 > nul
echo playerName= %playerName%>playerData.dll
echo playerRace= %playerRace%>>playerData.dll
echo playerHP= %LeveledUpPlayerHP%>>playerData.dll
echo playerSPD= %LeveledUpPlayerSPD%>>playerData.dll
echo playerATK= %LeveledUpPlayerATK%>>playerData.dll
echo playerDEF= %LeveledUpPlayerDEF%>>playerData.dll
The playerName and playerRace are all loaded in prior to this section of the code. Ping is used just as a wait function to let the file delete before echoing new data. Seems to work okay. Thanks all
try this (output is in %inifile%.new):
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
SET "inifile=file"
FOR /f %%a IN ('^<"%inifile%" find /c /v ""') DO SET /a lines=%%a
< "%inifile%" (
FOR /l %%a IN (1,1,%lines%) DO (
SET "line="
SET /p "line="
IF NOT "!line:playerHP=!"=="!line!" (
FOR /f "tokens=2delims= " %%b IN ("!line!") DO SET /a HP=%%b*12/10
SET "line=playerHP= !HP!"
)
ECHO(!line!
))>"%inifile%.new"
Input/output:
>type file
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
>test.bat
>type file.new
playerName= Marche
playerRace= Elf
playerHP= 120
playerSPD= 200
playerATK= 120
playerDEF= 70
Presumeably it does not matter what order the values appear in you file. If that is so, then the following will effectively "edit" your file.
It first uses FINDSTR to isolate the current playerHP value, and FOR /F to parse out the value from the string. SET /A increments the playerHP. Then a new file is created using FINDSTR to write all the current values except for playerHP, and then the new playerHP info is appended to the end.
#echo off
set "file=gameData.txt"
for /f "tokens=2 delims==" %%N in ('findstr /bl "playerHP=" "%file%"') do set /a "newHP=%%N*120/100"
>"%file%.mod" (
findstr /blv "playerHP=" "%file%"
echo playerHP=%newHP%
)
move /y "%file%.mod" "%file%" >nul
But why go to all that trouble. I should think you already have all your values in memory as environment variables. Simply make sure that all variables that are to be stored in a file start with a common unique prefix. In your example, they all start with "player", but you probably want something a little more generic - perhaps a symbol like #. So you could have #playerName, #playerRace, etc.
Simply update the values in memory as needed. When it comes time to save the current game state to a file, then all you need to do is
>"gameData.txt" set #
A brand new file will be created each time containing all the current values.
To load the values, you do exactly what jeb suggested:
for /f "usebackq delims=" %%A in ("gameData.txt") do set %%A
To save your data in a file, you could use a block like
(
echo playerName=%playerName%
echo playerRace=%playerRace%
echo playerHP=%playerHP%
) > player.ini
And to load it you could use
for /F "delims=" %%L in (player.ini) do set "%%L"

Resources