I'm trying to build a batch script that will iterate over a set of folders and give me the most recently modified file (and later check if the date of that file is 180 days old). Right now, what I'm working with is this:
setlocal EnableDelayedExpansion
for /f %%f in ('dir /b /s /od /tw "<some UNC path>\*.*"') do (
REM Make sure the variable is defined the first time we try to compare it
if NOT DEFINED fileDateTime set fileDateTime=%%~tf
if %%~tf LEQ !fileDateTime! (
set fileDateTime=%%~tf
set fileName=%%nxf
set filePath=\\%%~pf
))
This does not work.Specifically, everything except the comparison at the start works. It seems completely arbitrary how the computer parses the LEQ; I can't find a consistent pattern. It definitely isn't comparing two dates with each other.
The variable !fileDateTime! always has the same format as %%~tf, basically by definition. But Batch doesn't know what to do with it, or rather, I'm not sure how to tell Batch what to do with it.
I have tried using ForFile, but the path in question is a network share, so it fails (and for some reason the workaround with Net Use doesn't like to work either.)
Is there an easier way to get the most recent file in a folder and check how old it is?
(Also, the server holding the UNC path is a linux server, so if this is substantially easier in Bash, I could do that too.)
EDIT: if anyone is wondering how I fixed this, my solution was "realize that there's absolutely no reason I should be doing this is batch to begin with, install Python on the server, and script it in that instead." This will now be my go-to solution for batch problems in the future. But thank you all very much for the advice, which definitely would have helped if I didn't change tack.
The date you get is a string, not a date object like you'd get in an object-oriented language.
And the LEQ operator can only compare integers, not arbitrary strings.
Worse still, the date string you get is in a format that depends on your OS localization, AND on user preferences.
To do a meaningful comparison, you have to first convert your date strings to a julian date (An integer counting the number of days since an initial reference date.) Then compare those integers together.
For that I recommend that you use the :jdate function there:
https://www.dostips.com/DtCodeCmdLib.php#Function.jdate
Related
I'm new to batch. I want to move a file hello.bat to the startup folder, but only on a specific date.
How do I insert "if then" statements (e.g. If "date" Then "execution")?
Furthermore, how do I move a file?
I've tried this using what I've gathered from Google:
If %date% NEQ 2015/12/25 goto asdf
move c:\Users\USERNAME\AppData\hello.bat
c:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup
:asdf
It doesn't seem to be working, however - the move part works fine, but when I insert the If statement, it doesn't compile.
Can someone offer me a solution to this problem? I feel I would learn more from an example than reading something online.
The %date% variable is different depending on your system settings. To check the format of %date%, run the following command in a cmd window echo %date%.
In my system, the date format is Day 00/00/0000. So the following would be needed (string manipulation to remove the first four characters of the date).
if "%date:~4%" NEQ "12/25/2015" goto asdf
As a side note; you can simply goto :EOF (End Of File) if you just want the script to end.
How does one get yesterday's date format in a batch file?
I'd like it to look like so: M_d_yyyy
Note that if there's a single digit day and month, I'd like it to be single digits.
Example: 8_5_2013 is August 5th, 2013.
I looked around for a few days but couldn't find a solution.. any lead is much appreciated.
Nothing wrong with free 3rd party executables, but some of us are not allowed to use them on our work machines.
I have written a powerful hybrid JScript/batch utility called getTimestamp.bat that can do nearly any date and time computation on a Windows machine.
There are a great many options for specifying the base date and time, many options for adding positive or negative offsets to the date and time, many options for formatting the result, and an option to capture the result in a variable. Both input and output can be directly expressed as local time, UTC, or any time zone of your choosing. Full documentation is embedded within the script.
The utility is pure script that will run on any modern Windows machine from XP forward - no 3rd party executable required.
Assuming getTimestamp.bat is in your current directory, or better yet, somewhere within your PATH, then the following simple call will define a dt variable containing yesterday's date in M_D_YYYY format:
call getTimestamp -od -1 -f {m}_{d}_{yyyy} -r dt
Note: when I put a date in a file name, I like to use YYYY_MM_DD format because that format will sort chronologically when getting a directory listing.
I think you should get date.exe from UnxUtils.
date.exe --date="1 day ago" "+%-m_%d_%Y"
Download: http://sourceforge.net/projects/unxutils/files/unxutils/current/
Man page: http://www.ss64.com/bash/date.html
#echo off
setlocal
set magic="c:\unx\usr\local\wbin\date.exe" --date="1 day ago" "+%%-m_%%d_%%Y"
for /f %%i in ('%magic%') do set yesterdate=%%i
echo yesterdate = %yesterdate%
If you want to do it with just batch language, you'll end up with nearly 100 lines of incomprehensible batch code. UPDATE: or use dbenham's hybrid batch/JScript solution posted in the answer below, which at least uses sane Windows APIs.
See Also:
How to get current datetime on Windows command line, in a suitable format for using in a filename?
XCOPY /d is documented to take a date in the form dd-mm-yyyy but I can't find any mention of similar support for time.
Is there (or a workaround even) or do I have to download another command line tool for winxp?
There's no way to include time as a criteria in XCOPY. This is true for ROBOCOPY as well, even though it has many more configuration options than XCOPY.
The XXCOPY application will do what you ask -- but as you say, this costs money (for commercial uses, anyway).
http://www.xxcopy.com/xxtb_001.htm - search for "/DA:".
I have a situation where we have several thousand image files that have become corrupted on our server (Windows 2008 R2 x64). I have a working image file that I want to replace the corrupt files with. The files must retain the same name and path (size, timestamps, etc do not matter).
So the basic idea would be to replace each corrupt image file with the working file.
I do not write code, only the occasional windows batch file.
Should I use VB or PowerShell (or something else) for this? What will the script look like for this?
I apologize in advance if this question is too basic for stackoverflow.
You don't really need a batch file,
try looking at the for command
e.g.
FOR /R %f in (*.jpg) DO copy newfile.jpg "%f"
This should do a recursive search and copy newfile.jpg over the jpg's it finds.
It all boils down to how you are identifying the broken jpgs.
When I dont use a wild card for example
FOR /R %f in (broken.jpg) DO copy newfile.jpg "%f"
Then newfile.jpg gets copied to every subdirectory. If I use a wildcard ( *,?) the command works as expected. Is there a way to have this commend work with a (set) that does not contain wildcards?
I have a program who's generating some data in registry.
I save it with "reg export HKCU\Software\ProgramName\Data data.reg" (Unicode format).
I need to take it to other computer and import it there so the program from that computer could use the data.
But I have to remove some text lines from data.reg. The text lines are easy to find because they contain some strings (for example paths to exe and dlls, specific program settings like "name1=value1", "name2=value2",...).
Now I'm doing this manually (using Wordpad) every few days but maybe there is another way...
Oh and I can't install other programs on these computers (the access is restricted) so I have to use batch/cmd files.
What I tried so far:
- redirecting the export to "con" but is visual only not in a variable;
- using "for /F ..." but this works only with ANSI and removes blank lines.
The lines must be removed before importing because the settings of the program from the first computer must not be loaded into the registry keys of the program from the second computer.
Can somebody please help me...?
Thank you.
Use this code to loop the file contents line by line
FOR /F %z IN (yourfile.reg) DO ...
Then use conditionals to determine if this line is one you want to keep
IF (%z)==[put your key string here]
If so (or if not), then write that variable to the target file
#echo %z >> output.reg
You can replace the filenames with command line arguments, use %1, %2, etc.
All together, then:
FOR /F %z IN (%1) DO IF NOT (%z)==[skip this line] #echo %z >> %2
Since you didn't give some critical details, I am making some assumptions here. Further reading can be found at this excellent resource: http://www.robvanderwoude.com/batchfiles.php
An example would be nice, but could you use reg delete to delete the keys/values you want after importing your .reg file?