How to get the system date time format? - batch-file

I have a batch file that does some operations based on the date. It extracts the day, month and year and then creates a file with these variables. The trouble is the date format is different on different machines (dd/mm/yyyy, mm/dd/yyyy, ddd dd/mm/yyyy etc.). Is there a way to extract the date format first and then create the variables based on the extracted format in a batch file.

This should work on any machine from XP Pro and later.
#echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set "dt=%%a"
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 datestamp=%YYYY%%MM%%DD%
set timestamp=%HH%%Min%%Sec%
set fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause

try this:
#ECHO OFF &SETLOCAL
call:main
ECHO %ERRORLEVEL%
goto:eof
:main
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=3" %%A IN ('REG Query "HKEY_CURRENT_USER\Control Panel\International" /v sDate') DO SET lim=%%A
FOR /F "tokens=2,*" %%A IN ('REG Query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate') DO SET sdf=%%B
SET now=%date%
IF DEFINED lim (
FOR /F %%D IN ("!lim!") DO (
SET sdf=!sdf:%%~D= !
SET now=!date:%%~D= !
)
)
FOR %%A IN ("jan=1" "feb=2" "mar=3" "apr=4" "may=5" "jun=6" "jul=7" "aug=8" "sep=9" "oct=10" "nov=11" "dec=12") DO SET now=!now:%%~A!
FOR %%A IN (m o n t u e w d h r f i s a) DO SET now=!now:%%A=!
FOR %%A IN (%sdf%) DO (
SET tester=%%A
IF "!tester:ddd=!"=="!tester!" (
IF NOT "!tester:d=!"=="!tester!" (
SET ndf=!ndf! tday
) ELSE (
IF NOT "!tester:m=!"=="!tester!" (
SET ndf=!ndf! tmonth
) ELSE (
SET ndf=!ndf! tyear
)
)
)
)
CALL :Match %now%
FOR %%A IN (tyear tmonth tday) DO IF NOT DEFINED %%A (
>&2 ECHO An Error Occured - Check if it is EVEN POSSIBLE to work out what
>&2 ECHO the date is from the %%date%% variable^("%date%"^).
ENDLOCAL
EXIT /B 1
)
IF %tyear% LSS 99 SET tyear=20%tyear%
IF NOT "%tmonth:~0,1%"=="0" IF %tmonth% LSS 10 SET tmonth=0%tmonth%
IF NOT "%tday:~0,1%"=="0" IF %tday% LSS 10 SET tday=0%tday%
ENDLOCAL & EXIT /B %tyear%%tmonth%%tday%
:Match
FOR %%A IN (%ndf%) DO (
CALL SET %%A=%%1
SHIFT
)
This is pure batch and works on all XP systems without wmic, Vista, Win7 & 8.
Echo the date format:
FOR /F "tokens=2,*" %%A IN ('REG Query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate') do set "DateFormat=%%B"
echo %DateFormat%

Related

Add numbers with same text together

I would like to create a batch file in which I can see what I have collected in a game.
The game saves this information in a .txt file.
The output would look like this.
70x Silver.
Back Pearl.
41x Copper.
Amethyst.
Amethyst.
12x Silver.
Back Pearl.
21x Copper.
5x Silver.
Back Pearl.
Back Pearl.
Amethyst.
What I want to do now, is to add the items with the same name together, like this:
128x Silver.
4x Back Pearl.
62x Copper.
3x Amethyst.
There are hundreds of items with different names, not just these 4.
Would that be possible?
Any help would be appreciated. Thanks!
Another one!
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%l in (test.txt) do for /F "tokens=1*" %%a in ("%%l") do (
set "first=%%a"
if "!first:~-1!" equ "x" (set /A "num=!first:~0,-1!") else set "num=0"
if !num! equ 0 (
set "rest=%%l"
set /A "count[!rest: =_!]+=1"
) else (
set "rest=%%b"
set /A "count[!rest: =_!]+=num"
)
)
(for /F "tokens=2* delims=[]=" %%a in ('set count[') do (
set "item=%%a"
if %%b equ 1 (
echo !item:_= !
) else (
echo %%bx !item:_= !
)
)) > summary.txt
#ECHO OFF
SETLOCAL
rem The following settings for the source directory and filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q72672485.txt"
:: remove variables starting #
FOR /F "delims==" %%b In ('set # 2^>Nul') DO SET "%%b="
FOR /f "usebackqdelims=" %%b IN ("%filename1%") DO (
CALL :sub %%b
)
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /F "tokens=1,2delims==" %%b In ('set # 2^>Nul') DO (
SET "line=%%cx%%b"
ECHO !line:#= !
)
)>summary.txt
endlocal
type summary.txt
GOTO :EOF
:sub
SET "quantity=%1"
SET "line=%*"
IF /i "%quantity:~-1%"=="x" (SET /a quantity=%quantity:~0,-1%&SET "line=%line:* =%") ELSE SET quantity=1
IF %quantity%==0 SET /a quantity=1&SET "line=%*"
SET /a #%line: =#%+=quantity
GOTO :eof
Different approach...
Would that be possible? - Yes.
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (t.txt) do (
set " z=%%a"
set " z=!z:x =#!"
set " z=!z: =_!"
for /f "tokens=1,2 delims=#" %%b in ("!z!") do (
if "%%c" == "" (
set "x=1"
set "y=%%b
) else (
set "x=%%b"
set "y=%%c"
)
set /a #!y!+=!x!
)
)
(for /f "tokens=1,2 delims=#=" %%a in ('set #') do (
set "x=%%a"
set "y=%%bx "
echo !y:~0,4! !x:_= !
))>summary.txt
Output with your example data (I hope, alphabetic sorting is ok for you):
3x Amethyst.
4x Back Pearl.
62x Copper.
87x Silver.
(your calculation of 120 silver might be a bit optimistic with the given input data)
This is a different approach that use a "file merge" method. The overall code is somewhat simpler than other methods...
#echo off
setlocal EnableDelayedExpansion
set "lineNum=0"
(for /F "tokens=1,2* delims=:x " %%a in ('(type test.txt ^& echo 0x^) ^| findstr /N "[0-9][0-9]*x"') do (
if !lineNum! lss %%a call :locateLine %%a
set "line=%%c"
set /A "count[!line: =_!]+=%%b"
)) < test.txt
set "count[="
(for /F "tokens=2* delims=[]=" %%a in ('set count[') do (
set "item=%%a"
if %%b equ 1 (echo !item:_= !) else echo %%bx !item:_= !
)) > summary.txt
goto :EOF
:locateLine num
set /A "lineNum+=1" & set /P "line=" & if errorlevel 1 exit /B
if %lineNum% lss %1 set /A "count[%line: =_%]+=1" & goto locateLine
exit /B
Another approach (splitting the file into items with and without quantity) (also fixing the Pollux Infusion issue in my first answer):
#echo off
setlocal enabledelayedexpansion
REM process lines without quantity:
for /f "delims=" %%a in ('type test.txt^|findstr /vrc:"[0123456789][0123456789]*x "') do call :count 1 "%%a"
REM process lines with quantity:
for /f "tokens=1*delims=x " %%a in ('type test.txt^|findstr /rc:"[0123456789][0123456789]*x "') do call :count %%a "%%b"
REM reformat:
(for /f "tokens=1,2 delims=#=" %%a in ('set #') do (
set "count=%%bx "
set "line=!count:~0,5!%%a" &REM including '1x'
if %%b==1 set "line= %%a" &REM supressing '1x'
echo !line:_= !
))>summary.txt
type summary.txt
goto :eof
:count
set item=%~2
set "item=%item: =_%"
set /a #%item% +=%1
Included both with and without 1x. Remove the line, you don't want.

Batch - Converting the date modified of a file into a UNIX timestamp

I need to transform the last modifiaction dates for a set of files in a folder into a unix timestamp, timestamp only needs to be accurate to the day, this is so i can eventually delete files older than 12 months
I am currently implementing it as follows
#echo off
setlocal
set fileLocation="someLocation"
echo %fileLocation%
call :GetUnixTimeToday UNIX_TIME
call :GetUnixTimeFile UNIX_FILE
set /a leadtime=%UNIX_TIME%-31536000
set /a check=%UNIX_TIME%-%leadtime%
echo %UNIX_TIME% seconds have elapsed since 1970-01-01 00:00:00 (todays date)
echo %leadtime% seconds to compare to (comparison date)
echo %check%
pause
for %%i IN ("%fileLocation%") DO (
echo %%i
for %%a in ("%%i\*.*") do (
echo "%%a"
for /f "tokens=1-4 delims=: " %%G in ('echo %%~ta') do (
set date=%%G
set hour=%%H
set min=%%I
set ampm=%%J
echo "%UNIX_TIME%" "%%G"
)
echo exit inner
call :GetUnixTimeFile UNIX_FILE
echo %UNIX_FILE%
pause
)
echo exit mid
pause
)
echo exit total
pause
goto :EOF
:GetUnixTimeToday
setlocal enableextensions
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do (
set %%x)
set /a z=(14-100%Month%%%100)/12, y=10000%Year%%%10000-z
set /a ut=y*365+y/4-y/100+y/400+(153*(100%Month%%%100+12*z-3)+2)/5+Day-719469
set /a ut=ut*86400+100%Hour%%%100*3600+100%Minute%%%100*60+100%Second%%%100
endlocal & set "%1=%ut%" & goto :EOF
:GetUnixTimeFile
setlocal enableextensions
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do (
set %%x)
set /a z=(14-100%Month%%%100)/12, y=10000%Year%%%10000-z
set /a ut=y*365+y/4-y/100+y/400+(153*(100%Month%%%100+12*z-3)+2)/5+Day-719469
set /a ut=ut*86400+100%Hour%%%100*3600+100%Minute%%%100*60+100%Second%%%100
endlocal & set "%1=%ut%" & goto :EOF
goto :eof
At the moment the last modification dates are coming out in the format dd/mm/yyyy for each file in the folder
is it possible to adjust :GetUnixTimeFile to look for the file location instead of wmic path win32_utctime?
or would it be better to parse the date=%%G into a its individual components and then run it through :GetUnixTimefile ?
any help is greatly appreciated!

How to add time stamp in the beginning of batch file result

How can I add time stamp in the beginning of batch file results?
Here's my current code:
set dt=%date:~10,4%%date:~4,2%%date:~7,2%
set tm=%time:~0,2%%time:~3,2%%time:~6,2%
ping www.google.com -t -l 1 >PingLog_%dt%-%tm%.txt
I want to the result to be similar to this:
[hh:mm:ss] Reply from 120.89.12.38: bytes=1 time=1ms TTL=59
Small edit to add formatting:
It's tested and works well here - though the time format on this PC is 24 hour time, which makes it work well.
#echo off
setlocal enableDelayedExpansion
set dt=%date:~10,4%%date:~4,2%%date:~7,2%
set tm=%time:~0,2%%time:~3,2%%time:~6,2%
for /l %%# in (1,1,100) do (
set t=!time:~0,2!:!time:~3,2!:!time:~6,2!
for /f "tokens=* delims=" %%# in ('ping www.google.com -t -l 1 -n 1^|find /i "reply"') do (
echo [!t!] %%#
)
)
pause & goto :EOF
You can try like this :
#echo off
setlocal enableDelayedExpansion
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%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
pause
Set TmpLog=TmpLog.txt
Set Log=PingLog_%MM%-%DD%-%YYYY%-%HH%-%Min%-%Sec%.txt
If exist %TmpLog% Del %TmpLog%
If exist %Log% Del %Log%
echo %Log%
(
for /l %%# in (1,1,100) do (
set t=!time:~0,2!:!time:~3,2!:!time:~6,2!
for /f "tokens=* delims=" %%# in ('ping www.google.com -t -l 1 -n 1^|find /i "TTL"') do (
echo [!t!] %%#
)
)
)>>%TmpLog%
cmd /u /c type %TmpLog% > %Log%
pause & Start "" %Log%

How to add date condition in batch file

I have a batch file in my Startup folder. How Can I add a condition in the batch file that only execute the command if the system date is between 5th-25th of the current month and date is 6-11am.
I cant use task scheduler for this task.
Thanks in advance!
#echo off
pushd "%temp%"
makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
set "current-date=%%e-%%b-%%c"
set "current-time=%%d"
set "weekday=%%a"
)
del ~.*
popd
rem echo %current-time%
for /f "tokens=1,2,3 delims=-" %%a in ("%current-date% ") do (
set year=%%a
set mon=%%b
set day=%%c
)
echo %day%
for /f "tokens=1,2,3 delims=:" %%a in ("%current-time% ") do (
set hh=%%a
set mm=%%b
set ss=%%c
)
echo %hh%
if %day% LEQ 25 if %day% GEQ 5 if %hh% LEQ 11 if %hh% GEQ 6 (
echo execute my thing
)

reg query a key value based on another key value

What I'm trying to do is have a batch script return the uninstall link for a program. So basically I want something like this:
Select UninstallString from HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall where DisplayName='Sublime Text 1.0"
I'm using
reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S^|find " DisplayName"
to initially get a list of programs, which then get put in a menu, then I select the program to uninstall and it's supposed to go to that program's registry in HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall and get it's UninstallString value
Try this:
#echo off&setlocal enabledelayedexpansion
set "regroot=HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
set "file=%~dpn0.txt"
set /a fcount=0
for /f "delims==" %%i in ('set $ 2^>nul') do set "%%i="
if exist "%file%" (
for /f "usebackqtokens=1*delims=|" %%i in ("%file%") do (
set /a fcount+=1
set "$d%%j=%%j"
set "$u%%j=%%i"
)
goto:menu
)
echo(building "%file%", please wait
for /f "delims=" %%i in ('reg query "%regroot%"') do (
set "DN="& set "US="
for /f "tokens=2*" %%j in ('reg query "%regroot%\%%~ni" /v DisplayName 2^>nul^|find /i "DisplayName"') do set "DN=%%~k"
for /f "tokens=2*" %%j in ('reg query "%regroot%\%%~ni" /v UninstallString 2^>nul^|find /i "UninstallString"') do set "US=%%~k"
if not "!DN!"=="" if not "!US!"=="" if not defined $d!DN! (
>>"%file%" echo(!US!^|!DN!
set /a fcount+=1
set "$d!DN!=!DN!"
set "$u!DN!=!US!"
<nul set/p"=."
)
)
echo(
:menu
echo(%fcount% programs with uninstall strings found.
:loop
set /a pcount=0
set "program="
set /p "program=type a program name (q=quit): "
if not defined program goto:loop
if "%program%"=="q" goto:eof
echo(
for /f "tokens=2delims==" %%i in ('set $d ^|findstr !program! 2^>nul') do (
echo(%%i
echo(!$u%%i!
echo(
set /a pcount+=1
)
if %pcount% equ 0 (echo(!program! not found.) else echo(%pcount% program(s^) found.
goto:loop
You can use some of findstr's REGEX capabilities (eg. /i for case insensitive search). Please note: to search for all programs starting with "M" you can use "^$dM" or /b $dM. Searchable strings have always a leading $d.
Try this "two-liner":
for /f "tokens=7 delims=\" %%a in ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S /F "MySoftware" ^| find "{"') do set ProgramUninstallRegKey=%%a
for /f "skip=1 tokens=3*" %%a in ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\%ProgramUninstallRegKey% /V "UninstallString"') do set ProgramUninstallString=%%a %%b

Resources