Trying to write a script to get date 7 days from today and use as argument to my program [duplicate] - batch-file

In a batchfile, how do I store the output of a powershell command in a variable
This isn't working
set yest=powershell get-date((get-date).addDays(-1)) -uformat "%Y%m%d"
powershell get-date((get-date).addDays(-1)) -uformat "%Y%m%d"
gives 20130623
set yest=powershell get-date((get-date).addDays(-1)) -uformat "%Y%m%d"
echo %yest%
gives powershell get-date((get-date).addDays(-1)) -uformat "md"

The closing braces and percent need to be escaped/doubled.
#echo off
for /f "delims=" %%a in ('powershell get-date((get-date^).addDays(-1^)^) -uformat "%%Y%%m%%d"') do set d8=%%a
echo %d8%
pause

Related

Create a set of folders with cmd - Set a loop variable with a space

I don't know if its age or lack of practice. Either way I cannot wrap my head around this issue. I am trying to set a subroutine but the string that I am passing along are being split because of the space in string 3 and 4.
SET SubA=String1,String2,String 3,String 4
FOR %%A IN (%SubA%) DO MD "%%A"
I've tried parenthesis around the string
The <> brackets like Microsoft says to use. I have also tried this line below without success.
setlocal enableDelayedExpansion
For /F "tokens=* delims=" %%A IN (%Var%) DO MD "%%A"
Also I would love if possible could I make an list, possibly with an array. Like in Power shell I could do this. I really need to keep in the same batch file so the user could edit the list. I am aware that I could use caret but the easier I can make it for my client the better.
$Folders (
String1
String2
String 3
String 4
)
Edit: My desired result is to have this script create a set of folders like those pictured.
The simplest pure batch-file solution that doesn't require trickery is to use for's ability to enumerate space-separated tokens.
For this to work as intended, tokens that themselves contain spaces must be double-quoted:
#echo off & setlocal
:: Space-separated list of folder names, with names that contains
:: spaces themselves double-quoted.
SET SubA=String1 String2 "String 3" "String 4"
:: Loop over the list elements and create a directory for each.
FOR %%A IN (%SubA%) DO MD %%A
As Compo's helpful answer implies, you could actually pass this list to a single invocation of
MD: MD %SubA%
Unfortunately, as far as I know, batch files do not offer a convenient way to define lists in a one-item-per-line format.
However, you could provide the list of names via an external file, with each name on its own line (no double-quoting needed), which can then be parsed with for /f; e.g.:
#echo off & setlocal
:: Determine the full path of the file "names.txt"
:: located in the same folder as this batch file.
set "nameList=%~dp0names.txt"
:: Loop over all names in the file and call `md` with each.
for /f "usebackq delims=" %%n in ("%nameList%") do md "%%n"
And input file names.txt would then contain something like:
String1
String2
String 3
String 4
The simplest way to 'make' your directories is probably like this:
Set "SubA=String1,String2,String 3,String 4"
MD "%SubA:,=" "%" 2>NUL
As for working with the initial variable, and using it array like, you could do it like this:
#Echo Off & SetLocal EnableExtensions EnableDelayedExpansion
Set "SubA=String1,String2,String 3,String 4"
For /F "Delims==" %%G In ('"(Set Index[) 2>NUL"') Do Set "%%G="
Set "i=0"
Set "Index[!i!]=%SubA:,=" & Set /A i += 1 & Set "Index[!i!]=%"
(Set Index[) 2>NUL && Pause
Or you could do it like this:
#Echo Off & SetLocal EnableExtensions EnableDelayedExpansion
Set "SubA=String1,String2,String 3,String 4"
For /F "Delims==" %%G In ('"(Set Index[) 2>NUL"') Do Set "%%G="
Set "i=-1"
For %%G In ("%SubA:,=","%") Do (Set /A i += 1
Set "Index[!i!]=%%~G")
(Set Index[) 2>NUL && Pause
Here is another way to create the directories using the PowerShell that is already on your system if it is still supported by Microsoft. When you are satisfied that the correct directories will be created, remove the -WhatIf from the mkdir command.
SET "SubA=String1,String2,String 3,String 4"
powershell -NoLogo -NoProfile -Command ^
"'%SubA%'.split(',') | ForEach-Object { mkdir $_ -WhatIf | Out-Null }
A better way would be to test to see if the directory already exists before trying to create it.
SET "SubA=String1,String2,String 3,String 4"
powershell -NoLogo -NoProfile -Command ^
"'%SubA%'.split(',') | ForEach-Object {" ^
"if (-not (Test-Path -Path $_)) { mkdir $_ | Out-Null }" ^
"}"

extracting a changing and unknown hashcode from text document in batch

i wanted to code a little update tool for a server.jar file to save me all the effort of doing it manually
the program i'm using creates a folder which contains a file when a new update is released. this is pretty much how the program works:
get hash of current server.jar
find latest created folder (eg. update12)
open the file in the update12 folder (eg. update12.txt)
***extract the hash code -> %newHash%*** thats where im having the issue
compare the extracted hashcode (%newHash%) and the calculated hashcode (%currentHash%)
if they are not equal go to www.downloadupdate.com/updates/%newHash%/server.jar
download the file and replace the old server.jar with the new one.
the issue i am having is that i cant read out the hash in the update12.txt the file is about 36000 symbols long and in one line only
"server": {"sha1": "16f18c21286a3f566d3d0431d13aa133bebe6eff"
i want to detect the "server": {"sha1": " part and copy the hash after that
i tried many options i found on this forum but none seemed to work
like this one
set /p txt=<update12.txt
pause >nul
echo %txt%
pause >nul
for /f %%i in ('powershell -noprofile -c "('%txt:"=\"%' -split '\""')[1]"') do set id=%%i
echo %id%
just caused the batch file to close instantly
furthermore set /p txt=
if you have any solution i would be grateful to hear it
#echo off
Setlocal EnableDelayedExpansion
xcopy %appdata%\.minecraft\versions\%MCversion%\%MCversion%.json %appdata%\.minecraft\versions\%MCversion%\%MCversion%.text*
ren %appdata%\.minecraft\versions\%MCversion%\%MCversion%.text %MCversion%.txt
set search1=
set search2=,
set search3=:
set textFile=%appdata%\.minecraft\versions\%MCversion%\%MCversion%.txt
:PowerShell
SET PSScript=%temp%\~tmpStrRplc.ps1
ECHO (Get-Content "%textFile%").replace("%search1%", "") ^| Set-Content "%textFile%">"%PSScript%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
SET PSScript=%temp%\~tmpStrRplc.ps1
echo done.
ECHO (Get-Content "%textFile%").replace("%search2%", "") ^| Set-Content "%textFile%">"%PSScript%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
SET PSScript=%temp%\~tmpStrRplc.ps1
echo done.
ECHO (Get-Content "%textFile%").replace("%search3%", "") ^| Set-Content "%textFile%">"%PSScript%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
SET PSScript=%temp%\~tmpStrRplc.ps1
echo done.
:skip
ECHO (Get-Content "%textFile%").replace("server", "`r`nlookup") ^| Set-Content "%textFile%">"%PSScript%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
echo done.
for /f %%a in ('findstr "lookup\"{\"sha1\"\"" %textFile%') do set "newVersion=%%a"
set newVersion=%newVersion:~15,40%
echo %newVersion%
del %textFile%
pause
:exit
exit
this code works for me, what it does:
copy the "update12.txt"
look for " " "," and ":" in the copied txt and delete the symbols
look for server replace it with a "*linebreak*lookup"
find the string lookup"{"sha1""
trim the edges of the string with 15,40
done.

Batch Script for Checking time

Is it possible to check if the time is in between two ranges and then perform an action based on it.
For eg: I want to perform an action only when the current time is not in between 11.00 PM and 6.00 A.M.
Here's what I have so far but I am unable to pin the in between part.
set "currentTime=!TIME::=!"
set "currentTime=!currentTime:,=!"
set "_bit_compare=leq"
set "compareTime=2300"
set "compareTime1=600"
(time /t | findstr /l "AM PM" || set "_bit_compare=gtr")>nul
if "!currentTime:~0,4=!" %_bit_compare% "!compareTime!" (
do somethinf
)
And just to justify my comment, using wsh, (vbscript), from a batch-file:
<!-- :
#"%__AppDir__%cscript.exe" //NoLogo "%~f0?.wsf"
#If ErrorLevel 1 Exit /B
#Rem Your Commands go below here
#Echo Within range
#Pause
#Rem Your commands end above here
#Exit /B
-->
<Job><Script Language="VBScript">
If Hour(Now())<=22 AND Hour(Now())>=6 Then
WScript.Quit(0 Mod 255)
Else
WScript.Quit(1 Mod 255)
End If
</Script></Job>
I have used Remarks to show you where you put your command or commands, and have provided two lines for demonstration purposes, (which you are free to remove once tested).
It is a few lines more to do this in a batch file but you essentially want to get the time in a standard format. You can do that by calling out to WMIC. I am just using the hour to compare. I did not see any need to use minutes based on the provided example saying it is not in between 11.00 PM and 6.00 A.M. I am using a 1 to prefix the comparison incase of leading zeros in the hour.
#echo off
set "compareTime1=23"
set "compareTime2=06"
REM GET DATE and TIME
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
SET "YYYY=%dt:~0,4%"
SET "YY=%dt:~2,2%"
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%"
IF 1%HH% LSS 1%compareTime1% IF 1%HH% GTR 1%compareTime2% (
ECHO LETS DO SOMETHING
)
This is relatively easy to write using PowerShell. If you are on a supported Windows system, PowerShell will be available. This also overcomes a myriad of problems with regional variations in cmd.exe.
$h = [int](Get-Date -Format "HH")
if ($h -le 8 -or $h -ge 23) { & notepad.exe }"
To use it in a .bat file script, you could:
powershell -NoLogo -NoProfile -Command ^
"$h = [int](Get-Date -Format "HH");" ^
"if ($h -le 8 -or $h -ge 23) { & notepad.exe }"

Display Line (n) in a text file In Command Prompt

My text file include with 23 lines (lines include: !#$:/;" )
How can i only display line 3? in or 7? or 19?
I tried all commands was in stackoverflow
Example:
setlocal enabledelayedexpansion
#echo off
for /f "delims=" %%i in (mytext.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))
that's only show first line
#Compo has given a good answer. This is only to expound on it. Using aliases like GC should not be put into scripts. At the command line, sure, go ahead and reduce typing if you feel like it. Also, spelling out the parameter names provides more information and aids faster understanding.
To get only line 3.
GC .\mytext.txt -T 3|Select -L 1
Get-Content -Path '.\mytext.txt' -TotalCount 3 | Select-Object -Last 1
From the CMD console (Command prompt): (to get only line seven (7)
PowerShell "GC .\mytext.txt -T 7|Select -L 1"
PowerShell -NoProfile "Get-Content -Path '.\mytext.txt' -TotalCount 7 | Select-Object -Last 1"
To get lines 3 through 7:
$FirstLine = 3
$LastLine=7
powershell -NoProfile -Command "Get-Content -Path '.\t.txt' -TotalCount $LastLine | Select-Object -Last ($LastLine - $FirstLine + 1)"
Or, in a cmd.exe batch script.
SET "FIRSTLINE=3"
SET "LASTLINE=7"
powershell -NoProfile -Command ^
"Get-Content -Path '.\t.txt' -TotalCount %LASTLINE% |" ^
"Select-Object -Last (%LASTLINE% - %FIRSTLINE% + 1)"
#echo off
setlocal
set "FILE_TO_PROCESS=%~f1"
set /a LINE_NUMBER=%~2
set /a trim=LINE_NUMBER-1
break>"%temp%\empty"&&fc "%temp%\empty" "%FILE_TO_PROCESS%" /lb %LINE_NUMBER% /t |more +4 | findstr /B /E /V "*****"|more +%trim%
endlocal
try with this bat (called lineNumber.bat) the first argument is the file you want to process the second is the line number:
call lineNumber.bat someFile.txt 5
There are a couple of ways to do this. Your first option is to go through the for loop normally and break out of the loop once you reach the desired line.
#echo off
:: Specify which line to return
set get_line=7
:: Skip all lines before it, then print the next line and abort
set /a get_line-=1
for /F "skip=%get_line% delims=" %%A in (mytext.txt) do (
echo %%A
goto :end_loop
)
:end_loop
Your other option is to store all lines before the unwanted line in a temp variable and then display the next line.
#echo off
setlocal enabledelayedexpansion
:: Specify which line to return
set get_line=7
:: Skip all lines before it, then print the next line and abort
set /a get_line-=2
(
for /L %%A in (0,1,%get_line%) do set /p skip_line=
set /p return_line=
) <file.txt
echo !return_line!
Note that the first option is not suited for returning the first line of the script.
Since you said 'display', why not give PowerShell a shot:
From the PowerShell console:
GC .\mytext.txt -T 3|Select -L 1
From the CMD console (Command prompt):
PowerShell "GC .\mytext.txt -T 7|Select -L 1"
From a batch file:
#(PowerShell "GC .\mytext.txt -T 19|Select -L 1"&Pause)

How do I get a batch file variable assigned to another variable?

I have the following code:
for /f "tokens=1 delims=," %%i in (%T1R%.orignal) do (
set LINE="%%i"
set LINE1=%LINE%
echo %LINE1% >> %T1R%
)
Which is producing the following:
...
set LINE=" <Reference Include="Elmah">"
set LINE1=
echo 1>>C:\Temp\sync-msbuild-1R.txt
...
I've look at other similar questions and it appears that this should work, but it isn't on my system.
I'm not sure what exactly your code is supposed to achieve (why not use Lineinstead of LINE1 or even better %%i directly), but if you want to use variables defined within a loop, you should use delayed expansion:
SETLOCAL ENABLEDELAYEDEXPANSION
Then use ! instead of %:
SET LINE1=!LINE!
I could not find an answer that would allow me to have two SET commands within the DO block so I ended up solving the question by using PowerShell to accomplish the task:
PowerShell -Command "((Get-Content %T1R%) | Foreach-Object {$_ -replace '""[^\w]*>', ''} | Set-Content %T1R%)"

Resources