Time format and leading/trailing zeros/spaces - batch-file

I want to create a folder that uses TIME formatted in a specific way. I want the format to be in hh.mm.ss since you can't use a : in a folder name.
When I use set CurTime=%time:~0,2%.%time:~3,2%.%time:~6,2%, I get an output with a leading space before 10:00 AM and five trailing spaces as well (not sure why). I can remove the spaces by adding the line set CurTime=%CurTime: =%, but I want to add a leading zero if the time is earlier than 10:00 AM.
How can I do this?
Edit for clarification:
I have the time formatted the way I want it, but I want to replace the leading space with a 0 if the hh portion is less than 10. This is not a duplicate question of How to get current datetime on Windows command line, in a suitable format for using in a filename?.

If you have read this ==> Windows batch file redirect output to logfile with date/time
You can be able to do like this one :
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo stamp: "%stamp%"
pause
echo datestamp: "%datestamp%"
pause
echo timestamp: "%timestamp%"
pause
set MyVar=%HH%.%Min%.%Sec%
echo My desired Variable in this format hh.mm.ss to use is : %MyVar%
pause
mkdir "c:\%MyVar%"
pause

set "mytime=%time:~0,-8%"
set "mytime=%mytime: =0%"
set "mytime=%mytime::=.%"
echo "%mytime%"
should show the result you want. The first line removes the last 8 characters from time (which should be the 5 spaces + .dd) and the other two make the substitution of unwanted characters.
The reason for the 5 trailing spaces may be that some time formats allow " a.m." and the easy way is to simply replace the unwanted parts with spaces.

There are many ways to achieve your goal.
Here's a crazy untested one:
#ECHO OFF
SET "CurTime="
FOR /F "TOKENS=2-4 DELIMS=: " %%A IN ('ROBOCOPY/NJH /L "\|" NULL'
) DO IF NOT DEFINED CurTime SET "CurTime=%%A.%%B.%%C"
ECHO(%CurTime%
TIMEOUT -1

Related

Batch Script Timestamp Variable without spaces YYYY-MM-DD-HH-MM-SS

I've created a timestamp variable in a batch script like so...
set TIMESTAMP=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%
There is an issue though when the HH is only a single digit I get...
YYYY-MM-DD- 2-MM-SS
instead of
YYYY-MM-DD-02-MM-SS
How do I consistently generate the timestamp without spaces?
set "timestamp=%timestamp: =0%"
replaces spaces with zeroes.
See set /? from the prompt for documentation.
Don't use locale/user settings dependent date time variables but wmic:
#Echo off
For /f "delims=." %%A in (
'wmic os get LocalDateTime^|findstr ^^20'
) Do Set DT=%%A
Set "TIMESTAMP=%DT:~0,4%-%DT:~4,2%-%DT:~6,2%-%DT:~8,2%-%DT:~10,2%-%DT:~12,2%"
Set TimeStamp
Sample output:
> SO_45465890.cmd
TIMESTAMP=2017-08-02-18-42-07
Or use PowerShell and let it do the formatting:
#Echo off
For /f %%A in ('powershell -NoP -C "get-date -f \"yyyy-MM-dd-HH-mm-ss\""') Do Set TimeStamp=%%A
Set TimeStamp

Reformatting Web Query Results for use in Batch

This is working, but doesn't feel elegant to me. I'm creating an automated movie archive script in batch and would like to automatically find a movie title based on the disc volume name. The web query is done via tmdb, but returned results is difficult to parse since it isn't meant for batch. The results would be a contiguous line like:
{"page":1,"results":[{"poster_path":"\/5ttOaThDVmTpV8iragbrhdfxEep.jpg","adult":false,"overview":"At the height of the Cold War, a mysterious criminal organization plans to use nuclear weapons and technology to upset the fragile balance of power between the United States and Soviet Union. CIA agent Napoleon Solo and KGB agent Illya Kuryakin are forced to put aside their hostilities and work together to stop the evildoers in their tracks. The duo's only lead is the daughter of a missing German scientist, whom they must find soon to prevent a global catastrophe.","release_date":"2015-08-13","genre_ids":[35,28,12],"id":203801,"original_title":"The Man from U.N.C.L.E.","original_language":"en","title":"The Man from U.N.C.L.E.","backdrop_path":"\/bKxcCNv2xq8M3GD5iSrv9bMGDVa.jpg","popularity":5.346674,"vote_count":1842,"video":false,"vote_average":7},{"poster_path":"\/3VScfiBmE1loQxMkuN1suALv4f8.jpg","adult":false,"overview":"When THRUSH steals a nuclear weapon and demands a ransom delivered by Napoleon Solo, UNCLE recalls him and his partner to duty.","release_date":"1983-04-05","genre_ids":[28,80,53,10770],"id":94116,"original_title":"The Return of the Man from U.N.C.L.E.: The Fifteen Years Later Affair","original_language":"en","title":"The Return of the Man from U.N.C.L.E.: The Fifteen Years Later Affair","backdrop_path":"\/5LGBhGg5Tj9OSW4rD0itz0sYKPT.jpg","popularity":1.046707,"vote_count":5,"video":false,"vote_average":3.6}],"total_results":2,"total_pages":1}
You don't really know what you're going to get or how many titles will be returned. Dumping this into a file and reading back tokens doesn't make sense. The delimiter is a string (,") so I've come up with the following script which does function.
#echo off
setlocal EnableDelayedExpansion
set _tmdbReturn=
set _metaDataFile=
set _metaDataFile="C:\some path\metaData.txt"
set _metaDataFile=%_metaDataFile:~1,-1%
:: Do a movie title search based on a Disc Volume Label
for /f "usebackq delims=" %%a in (`PowerShell -Command "(new-object net.webclient).DownloadString('https://api.themoviedb.org/3/search/movie?api_key=xxx&query=The+Man+from+uncle')"`) do (set _tmdbReturn=%%a)
:: Result is in a contiguous string and the delimiter is a string with a comma and double quotes (,")
:: Replace delimiter string with a single character that does not occur in tmdb data
set _tmdbReturn=%_tmdbReturn:,"=#"%
set _tmdbReturn=%_tmdbReturn:"=%
:: replace unique single character with a line feed
set _tmdbReturn=!_tmdbReturn:#=^
!
:: Eliminate the special character
set _tmpdbReturn=!_tmdbReturn:#=!
:: Rewrite data to txt file with row separated data.
echo !_tmdbReturn!>"%_metaDataFile%"
set x=
set /a x=0
for /f "tokens=* delims=#" %%a in ('type "%_metaDataFile%"') do (
if !x!==0 (
set _newline=%%a
echo !_newline!>"%_metaDataFile%"
) else (
set _newline=%%a
echo !_newline!>>"%_metaDataFile%"
)
set /a x+=1
)
My question is two fold...is there a better way to do this? I also have not figured out how to write to the _metaDataFile without first dumping !_tmdbReturn! into a txt file. I've tried replacing the command of the last For Loop with
for /f "tokens=* delims=#" %%a in ('echo !_tmdbReturn!') do (
Only the first token writes yet
echo !_tmdbReturn!
displays the data properly producing the following:
{page:1
results:[{poster_path:\/5ttOaThDVmTpV8iragbrhdfxEep.jpg
adult:false
overview:At the height of the Cold War, a mysterious criminal organization plans to use nuclear weapons and technology to upset the fragile balance of power between the United States and Soviet Union. CIA agent Napoleon Solo and KGB agent Illya Kuryakin are forced to put aside their hostilities and work together to stop the evildoers in their tracks. The duo's only lead is the daughter of a missing German scientist, whom they must find soon to prevent a global catastrophe.
release_date:2015-08-13
genre_ids:[35,28,12]
id:203801
original_title:The Man from U.N.C.L.E.
original_language:en
title:The Man from U.N.C.L.E.
backdrop_path:\/bKxcCNv2xq8M3GD5iSrv9bMGDVa.jpg
popularity:5.346674
vote_count:1842
video:false
vote_average:7},{poster_path:\/3VScfiBmE1loQxMkuN1suALv4f8.jpg
adult:false
overview:When THRUSH steals a nuclear weapon and demands a ransom delivered by Napoleon Solo, UNCLE recalls him and his partner to duty.
release_date:1983-04-05
genre_ids:[28,80,53,10770]
id:94116
original_title:The Return of the Man from U.N.C.L.E.: The Fifteen Years Later Affair
original_language:en
title:The Return of the Man from U.N.C.L.E.: The Fifteen Years Later Affair
backdrop_path:\/5LGBhGg5Tj9OSW4rD0itz0sYKPT.jpg
popularity:1.046707
vote_count:5
video:false
vote_average:3.6}]
total_results:2
total_pages:1}
I'm attempting to redirect echo !_tmdbReturn! to the Find function extracting a particular value by name. I can do it in a file using findstr, but was trying it on the variable. I'm not fluent in batch so any suggestions are appreciated.
In case its useful for someone I settled on the following:
set x=
set /a x=0
set y=
set /a y=0
:: clean up the beginning of the data replace {" with " so poster_path is passed as a value
set _tmdbReturn=%_tmdbReturn:{"="%
set _tmdbReturn=%_tmdbReturn:~0,-1%
for /F "tokens=1* delims=[" %%a in ("!_tmdbReturn!") do ( set _tmdbReturn=%%b)
rem Separate the string in lines at ," delimiter
for /F "delims=" %%a in (^"!_tmdbReturn:^,^"^=^
% Do NOT remove this line %
!^") do (
set "line=%%a"
rem Eliminate quotes
set "line=!line:"=!"
rem Show lines of desired values only
for /F "tokens=1* delims=:" %%b in ("!line!") do (
if "%%b" equ "poster_path" set /a x+=1
if "%%b" equ "total_results" (
call set _movie.%%b=%%c
) else (
echo call set _movie[!x!].%%b=%%c
call set _movie[!x!].%%b=%%c
)
)
)
This give me an array of the returned results with structured object properties that I can use as my script morphs. This may be old hat to most, but I'm having fun!
The code below separates your long string in several lines:
#echo off
setlocal EnableDelayedExpansion
:: Do a movie title search based on a Disc Volume Label
:: for /f "usebackq delims=" %%a in (`PowerShell -Command "(new-object net.webclient).DownloadString('https://api.themoviedb.org/3/search/movie?api_key=xxx&query=The+Man+from+uncle')"`) do (set _tmdbReturn=%%a)
for /F "delims=" %%a in (input.txt) do set "_tmdbReturn=%%a"
rem Separate the string in lines at ," delimiter
for /F "delims=" %%a in (^"!_tmdbReturn:^,^"^=^
% Do NOT remove this line %
!^") do (
set "line=%%a"
rem Eliminate quotes
echo !line:"=!
)
I stored your long line in input.txt file for my testings.
About "redirect echo !tmdbReturn! to the Find function extracting a particular value by name"; if you show what exactly you want, perhaps I could show you how to get an equivalent result in a simpler way (without using find command)...
EDIT: Show just desired values
If you want not to create a file with all lines, but just show the lines of a desired value, then you may directly look for such a value in each line:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (input.txt) do set "_tmdbReturn=%%a"
rem Separate the string in lines at ," delimiter
for /F "delims=" %%a in (^"!_tmdbReturn:^,^"^=^
% Do NOT remove this line %
!^") do (
set "line=%%a"
rem Eliminate quotes
set "line=!line:"=!"
rem Show lines of desired values only
for /F "tokens=1* delims=:" %%b in ("!line!") do (
if "%%b" equ "original_title" echo %%b: %%c
)
)
You may also look for several values; just define the list of the desired values at beginning, enclosing all values by a certain delimiter character:
set "values=/title/original_title/"
... and change the if command inside the for by this one:
if "!values:/%%b/=!" neq "%values%" echo %%b: %%c

Folder with date format in mmddyyyy needed to be created using a bat file

I want to create a batch file which when clicked will create a folder with the name 12012016.
I tried with the command
mkdir "E:\Meru\Work\Trace Reports\%date:~6,4%%date:~3,2%%date:~0,2%
But its creates with the name 20160112.
Please help
This question implies that you have not tried to understand what is going on with this command...
Split in part: mkdir will create a directory with the name you have given.
The name you have given is build together using a fixxed string, you decided to use E:\Meru\Work\Trace Reports\ and three substrings from the system variable %date%.
Substring in batch works like this: %variable_name:~last character NOT to use,number of characters you need%. In your case it takes the year first, then the month and at last the day. You would just simply change the parts from %date:~6,4%%date:~3,2%%date:~0,2% to %date:~3,2%%date:~0,2%%date:~6,4%.
Notice!
The variable %date% has a different value based on the system settings for the time format. An alternative is the command wmic os get localdatetime which I covered in another answer here that will always have the same output format no matter what the settings are.
If you have read this ==> Windows batch file redirect output to logfile with date/time
You can be able to do like this one :
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo stamp: "%stamp%"
pause
echo datestamp: "%datestamp%"
pause
echo timestamp: "%timestamp%"
pause
set MyDateVar=%MM%%DD%%YYYY%
echo My desired Variable Date to use is : %MyDateVar%
pause
mkdir "E:\Meru\Work\Trace Reports\%MyDateVar%"
pause
Because several hours have now elapsed:
mkdir "E:\Meru\Work\Trace Reports\%date:~0,2%%date:~3,2%%date:~6,4%"

Batch Script: Search thru multiple files for part of an IP address and log it

I have multiple TraceRT log files containing 30 hops. I'm only looking for similar IP (ex. 192.168.1) and would like to log it on one file with:
1) Successful: %IP% found in %Filename%
2) Fail: Specified IP not found in %Filename%
I'm trying to use:
rem************************************************************
:START
# ECHO OFF
rem US date
set YEAR=%DATE:~10,4%
set MONTH=%DATE:~4,2%
set DAY=%DATE:~7,2%
rem US hour
set HOUR=%TIME:~0,2%
set MIN=%TIME:~3,2%
set SEC=%TIME:~6,2%
set HUNDREDS=%TIME:~9,2%
set HOURMIN=%HOUR%%MIN%
rem Make sure that hour has two digits
IF %HOUR% GEQ 10 goto twoh
set HOUR1=%TIME:~1,1%
set TWOHOUR=0%HOUR1%
goto fulltid
:twoh
set TWOHOUR=%HOUR%
:fulltid
set FULLTIME=%TWOHOUR%'%MIN%'%SEC%'%HUNDREDS%
set FTIME=%TWOHOUR%:%MIN%:%SEC%
#echo off & setLocal EnableDELAYedeXpansion
findstr /m "192.168.1" *.txt > FILENAME
echo on
for /f "tokens=*" %%a in (*.txt ^| find "192.168.1") do (
IF %%a neq %%b (
echo Suscessful: %%a %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
) ELSE (
echo Fail: Specified IP not found in %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
)
)
goto START
rem************************************************************
You have specified an invalid pipe | find. You cannot pipe (a) text file(s) into a command.
Either provide the file(s) as argument(s) to find, or use redirection (this works for a single file only but not for multiple ones nor */? patterns though).
You are using for /f not correctly.
It looks as if you wanted to parse the output of find. To accomplish that, but you must enclose the command within single-quotes '. Type for /? and see the help text for more details.
The following line of code should work:
for /f "tokens=*" %%a in ('find "192.168.1" *.txt') do (
To get current date and time, I strongly recommend to read variables %DATE% and %TIME% once only and within a single line! Otherwise you might run into problems, especially concerning the fractional seconds, which might not be equal between consecutive expansions.
To ensure %HOUR% to have two digits, you simply need to use set HOUR=0%HOUR% then set HOUR=%HOUR:~-2%.
Since a one-digit %HOUR% is prefixed by a space here, you can have it even simpler (thanks for your comment, #Stephan!) by just replacing the space by a zero: set HOUR=%HOUR: =0%.

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