I have a .bat file to execute in a windows server 2012 R2 machine. Problem is that I need to add an "if not equals" but when I try to execute it the code does not work.
I know that problem is in the if because I tried without the if and it works.
setlocal enabledelayedexpansion
set anno=%date:~6,4%
set mese=%date:~3,2%
set giorno=%date:~0,2%
set ore=%time:~0,2%
set minuti=%time:~3,2%
set secondi=%time:~6,2%
e:
mkdir "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
move \\gbjob09\Info-Bit\Sql_Ges\PRESENZE\2019\*.old "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
cd "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
for /f %%a in ('dir /b *.old') do (
set originalname=%%a
set timbrnumber=!originalname:~4,4!
if NOT %timbrnumber% == "0584" (
if NOT %timbrnumber% == "0585" (
set shortname=9!originalname:~4,4!
echo !shortname!
for /f "tokens=*" %%b in (%%a) do (
echo %%b!shortname!>> "Presenze.txt"
)
)
)
)
copy "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%\Presenze.txt" "E:\Presenze\presenze.txt"
exit
Like you can see the problem is only this really small part:
if NOT %timbrnumber% == "0584" (
I already tried to remove the double if but it still does not work.
I know that the old code (this one) works:
setlocal enabledelayedexpansion
set anno=%date:~6,4%
set mese=%date:~3,2%
set giorno=%date:~0,2%
set ore=%time:~0,2%
set minuti=%time:~3,2%
set secondi=%time:~6,2%
e:
mkdir "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
move \\gbjob09\Info-Bit\Sql_Ges\PRESENZE\2019\*.old "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
cd "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%"
for /f %%a in ('dir /b *.old') do (
set originalname=%%a
set shortname=9!originalname:~4,4!
echo !shortname!
for /f "tokens=*" %%b in (%%a) do (
echo %%b!shortname!>> "Presenze.txt"
)
)
copy "E:\Presenze\%anno%%mese%%giorno%%ore%%minuti%%secondi%\Presenze.txt" "E:\Presenze\presenze.txt"
exit
I only added a variable:
set timbrnumber=!originalname:~4,4!
that should work (it shouold get 4 characters after exclude 4 characters of the originalname variable) like shortname print 9 and 4 characters after exclude 4 characters of the originalname variable, but I'm not really sure because I don't really know windows batch (this is the first time that I use it and the original code was not mine).
After that I only need to check if timbrnumber is not "0584" and it's not "0585" but everything I tried was a fail.
In short, as your variable is being set and used inside a code block and double quoting is required both sides of the ==, this section should fix your issue:
if NOT "1!timbrnumber! == "10584" (
if NOT "!1timbrnumber!" == "10585" (
which can be better written as:
if 1!timbrnumber! neq 10584 (
if 1!timbrnumber! neq 10585 (
Another observation, your time:
set ore=%time:~0,2%
set minuti=%time:~3,2%
set secondi=%time:~6,2%
can be better created as:
set mytime=%time::=%
echo %mytime:0,6%
Related
I'm writing a small inventory script for my IT department and I've run into a little stumbling block while trying to save myself some time.
My goal is to store the current location in a temporary local file (this batch file will be run on a flash drive) so that when I move from one computer to the next, I only have to change the location if it is not accurate. Basically so that if I start in Unit 1, Building A, Room 3, I only have to confirm what is correct and change what isn't.
Perhaps the location confirmation code will give you a better idea of what's going on here.
#echo off
setlocal
setlocal EnableDelayedExpansion
if not exist location.tmp (
echo , , > location.tmp
)
for /f "tokens=1-3 delims=," %%i in (location.tmp) do (
if not "%%i" == " " (
set unit=%%i
)
if not "%%j" == " " (
set building=%%j
)
if not "%%k" == " " (
set room=%%k
)
)
for %%i in (unit,building,room) do (
call :SUB_GET %%i
)
echo !unit!,!building!,!room!> location.tmp
endlocal
exit /b 0
:SUB_GET
if not defined %1 (
set /p %1=What %1?
goto :EOF
)
set /p new%1=What %1? (default is !%1!)
if not "!new%1!" == "" (
set %1=!new%1!
)
Everything works, except for when I try to allow it to keep the default. I want to be able to just hit enter if the value is correct, (e.g. "What room? (default is 403)" hit enter and then it keeps 403)
The problem is, when I do that, even though the code checks the new environment variable (the input) to see if it is empty, it still assigns the old variable the value of the new one (empty string).
What's even more confusing is if I create an existing location.tmp with defaults (like 1,A,4) and hit enter to confirm each one, the batch statement echo !unit!,!building!,!room!>location.tmp executes, but location.tmp is unchanged.
Any ideas what's going on here?
set /p %1=What %1? (default is !%1!)
If you simply reply Enter to set /p then the variable remains unchanged.
So - no need for new%1 - and even then new would have been sufficient as there is no obvious need for newROOM etc. You'd have had to clear new judiciously to avoid retaining stale data though.
The delayed execution of the variables in the line echo !unit!,!building!,!room!>location.tmp is causing them to be expanded too late and thus the statement doesn't properly execute for whatever reason. Replacing them with normal %variables% fixes both issues. It turns out the comparison was working correctly, just not getting expanded in time.
EDIT: No idea why, but the above is incorrect. The below script works perfectly fine...
#echo off
setlocal
setlocal EnableDelayedExpansion
if not exist location.tmp (
echo , , > location.tmp
)
for /f "tokens=1-3 delims=," %%i in (location.tmp) do (
if not "%%i" == " " (
set unit=%%i
)
if not "%%j" == " " (
set building=%%j
)
if not "%%k" == " " (
set room=%%k
)
)
for %%i in (unit,building,room) do (
call :SUB_GET %%i
)
echo !unit!,!building!,!room!> location.tmp
endlocal
exit /b 0
:SUB_GET
if not defined %1 (
set /p %1=What %1?
goto :EOF
)
set /p %1=What %1? (default is !%1!)
I am trying to get a mover batch script to read the filenames in a folder and do things to them based on the filename before moving them.
I have no trouble getting the files to be moved but I can't get the doing stuff based on filename part right.
#ECHO on
setlocal enableDelayedExpansion
SET src_folder=c:\recordz
SET tar_folder=\\TOWER\Temprec
:LOOP
for /f "delims=" %%a IN ('dir "%src_folder%"\*.mpg /b') do (
set "var=%%~na"
Echo %var%
Rem this part is supposed to check if NFL is part of the filename
If NOT "%var%"=="%var:NFL=%" (
echo Found inside
REN "%src_folder%\%%~na.mpg" "%%~na.ts"
move %src_folder%\"%%~na.ts" %tar_folder%
) else (
echo No cigar
move %src_folder%\"%%~na.mpg" %tar_folder%
)
)
REM Crafty 5 minute delay...
PING 1.1.1.1 -n 1 -w 1800000 >NUL
GOTO LOOP
When I run the above, I get this:
C:\Scripts>(
set "var=Feux_20161003_21002200"
Echo
If NOT "" == "NFL=" (
echo Found inside
REN "c:\recordz\Feux_20161003_21002200.mpg" "Feux_20161003_21002200.ts"
move c:\recordz\"Feux_20161003_21002200.ts" \\TOWER\Temprec
) else (
echo No cigar
move c:\recordz\"Feux_20161003_21002200.mpg" \\TOWER\Temprec
)
)
ECHO is on.
Found inside
Although you have enabled the delayed expansion you are not using it. Change % to ! inside the loop.
for /f "delims=" %%a IN ('dir "%src_folder%"\*.mpg /b') do (
set var=%%~na
Echo !var!
Rem this part is supposed to check if NFL is part of the filename
If NOT "!var!"=="!var:NFL=!" (
echo Found inside
REN "%src_folder%\%%~na.mpg" "%%~na.ts"
move %src_folder%\"%%~na.ts" %tar_folder%
) else (
echo No cigar
move %src_folder%\"%%~na.mpg" %tar_folder%
)
)
This is my first batch program and I have been searching online but still struggling to write up a solution.
I have the following CSV file:
"RH",2013/06/15 02:14:58 -0400,"X","LQ3SUEEWPWKL6",005,
"FH",01
"SH",2013/06/14 00:00:00 -0400,2013/06/14 23:59:59 -0400,"LQ3SUEEWPWKL6",""
"CH","TransactionID","InvoiceID",
......
I'm trying to write a simple program to do the following:
If column1 = "RH", then extract column2 value (2013/06/15 02:14:58 -0400)
If column1 = "SH", then extract column4 value (LQ3SUEEWPWKL6)
and pipe output to a file.
This is my code so far but the if condition is not working for me
#echo off
:: Set input file in variable
::Set _InputFile=%1
:: Store input line into different variables
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
Set _var1=%%A
Set _var2=%%B
Set _var3=%%C
Set _var4=%%D
Set _var5=%%E
Set _var6=%%F
Set _var7=%%G
Set _var8=%%H
Set _var9=%%I
Set _var10=%%J
Set _var11=%%K
Set _var12=%%L
Set _var13=%%M
Set _var14=%%N
Set _var15=%%O
Set _var16=%%P
Set _var17=%%Q
Set _var18=%%R
IF "%_var1%"=="RH" echo %var2%
)
My CSV file looks fine in Excel and Notepad but when I execute the script to display the first variable, it looks like there's some garbage characters just before the "RH" on the first record - I cannot bypass it since I need to extract additional column data if var1 = "RH":
"RH"
FH
01
SH
CH
TransactionID,PaymentTrackingID,
SF
SF
SC
RF
CAD,CR,0
RF
USD,CR,0
RC
FF
(
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
if "%%~A"=="RH" echo %%~B
if "%%~A"=="SH" echo %%~D
)
)>youroutputfilename
Should work - no need to assign all the values to different variables - BUT if you plan to use them, then
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
...
Set _var17=%%Q
Set _var18=%%R
CALL :PROCESS
)
...
GOTO :EOF
:PROCESS
IF %_var1%=="RH" echo %_var2%
IF %_var1%=="SH" echo %_var4%
GOTO :EOF
Note that with this method, since you are assigning %%x to _varx then if %%x is quoted, the quotes will be INCLUDED in the value assigned. To remove the enclosing quotes (if they exist) use SET _varx=%%~x.
Addendum 20130703-1956Z for OP's problem
#ECHO OFF
SETLOCAL
SET _Inputfile=u:\noname1.txt
(
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
SET "RH="
SET "SH="
ECHO(%%A|FINDSTR /l /c:"\"RH\"" >NUL
IF NOT ERRORLEVEL 1 SET RH=Y
ECHO(%%A|FINDSTR /l /c:"\"SH\"" >NUL
IF NOT ERRORLEVEL 1 SET SH=Y
if DEFINED RH echo %%~B
if DEFINED SH echo %%~D
)
)>u:\youroutputfilename
TYPE u:\youroutputfilename
del u:\youroutputfilename
echo========First way
(
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
SET _var1=%%A
SET "RH="
SET "SH="
CALL :process
if DEFINED RH echo %%~B
if DEFINED SH echo %%~D
)
)>u:\youroutputfilename
TYPE u:\youroutputfilename
del u:\youroutputfilename
echo========Second way
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
SET _var1=%%A
IF "!_var1:~-4!"==""RH"" echo %%~B
IF "!_var1:~-4!"==""SH"" echo %%~D
)
)>u:\youroutputfilename
TYPE u:\youroutputfilename
del u:\youroutputfilename
echo========Third way
ENDLOCAL
GOTO :EOF
:process
IF "%_var1:~-4%"==""RH"" SET RH=Y
IF "%_var1:~-4%"==""SH"" SET SH=Y
GOTO :EOF
You have a parsing issue. First end the for loop with ), after this you can use the new variables:
#echo off
:: Set input file in variable
::Set _InputFile=%1
:: Store input line into different variables
FOR /F "tokens=1-18* delims=," %%A IN (%_InputFile%) DO (
Set "_var1=%%A"
Set "_var2=%%B"
Set "_var3=%%C"
Set "_var4=%%D"
Set "_var5=%%E"
Set "_var6=%%F"
Set "_var7=%%G"
Set "_var8=%%H"
Set "_var9=%%I"
Set "_var10=%%J"
Set "_var11=%%K"
Set "_var12=%%L"
Set "_var13=%%M"
Set "_var14=%%N"
Set "_var15=%%O"
Set "_var16=%%P"
Set "_var17=%%Q"
Set "_var18=%%R"
)
IF "%_var1%"=="RH" echo %var2%
You need to enable delayed expansion:
#echo off
setlocal EnableDelayedExpansion
set "_InputFile=..."
for /f "tokens=1-18* delims=," %%A in (%_InputFile%) do (
Set _var1=%%A
Set _var2=%%B
...
if "!_var1!"=="RH" echo !_var2!
)
as there was no answer to the "why does my line starts with "RH"", I'll do some gravedigging.
So, the  comes from the BOM (Byte Order Mark) which indicates the file is in UTF, and the way the bytes are written if necessary.
for the answer:
you can use
if x%_var1:RH=%x NEQ x%_var1%x (echo %_var2%)
this will check if RH is in %_var1% (if after replacing RH in the var, it is unchanged, RH is not in the var)
which means, whether the Bom is here or not is not important. Though, you'll have problems if you want an exact match.
another way to deal with it is to not include the bom in your file, which means saving either in ASCII or UTF-8 without BOM; Or using a tool to strip the bom from your UTF-8 file.
When running the following code in a windows batch file everything works aside from the string containing the asterisk, which is skipped. Checking the passed parameters by number (i.e. echo(%~6) I can see the asterisk - it's only when passed to the FOR loop that I have an issue:
#echo off
setlocal enableextensions enabledelayedexpansion
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!
#goto:end
#goto:eof
:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
echo(%*
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%*) do (
set /a xx=!xx!+1
echo !xx! - %%A
if !Concat_tempFlag!==1 (
set Concat_temp=!Concat_temp!%%~A
) else (
set Concat_tempFlag=1
)
)
set "%~1="%Concat_temp%""
#goto:eof
:End
echo(Bye
exit /b 0
I've attempted for /F (tokens=*) %%A in ('echo(%*') do ( as suggested here: Batch FOR loop with asterisk (and variations thereof) but with no luck. Any ideas? Thanks in advance.
Found the solution here: I need to match or replace an asterisk * in a batch environmental variable using only native Windows commands. Is this possible?
Full code below:
#echo off
setlocal enableextensions enabledelayedexpansion
set DEFAULT_AsteriskMarker=_xAsteriskMarkerx_
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!
#goto:end
#goto:eof
:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
set Concat_StringsToConcat=%*
echo(%Concat_StringsToConcat%
call:AsteriskFix Concat_StringsToConcat
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%Concat_StringsToConcat%) do (
set /a xx=!xx!+1
echo !xx! - %%A
if !Concat_tempFlag!==1 (
set Concat_temp=!Concat_temp!%%~A
) else (
set Concat_tempFlag=1
)
)
set "%~1="!Concat_temp:%DEFAULT_AsteriskMarker%=*!"
#goto:eof
:AsteriskFix
::https://stackoverflow.com/questions/11685375/i-need-to-match-or-replace-an-asterisk-in-a-batch-environmental-variable-using
set AsteriskFix_temp=!%~1!
if "%~2"=="" (
set AsteriskFix_marker=%DEFAULT_AsteriskMarker%
) else (
set AsteriskFix_marker=%~2
)
call:StrLen AsteriskFix_temp AsteriskFix_len
for /l %%x in (0,1,%AsteriskFix_len%) do if not "!AsteriskFix_temp:~%%x,1!"=="" if "!AsteriskFix_temp:~%%x,1!"=="*" (
set /a AsteriskFix_plusone=%%x+1
for /l %%y in (!AsteriskFix_plusone!, 1, !AsteriskFix_plusone!) do (
set AsteriskFix_temp=!AsteriskFix_temp:~0,%%x!%AsteriskFix_marker%!AsteriskFix_temp:~%%y!
)
)
set "%~1=!AsteriskFix_temp!"
#goto:eof
:StrLen
::http://www.dostips.com/DtCodeCmdLib.php#strLen
set "StrLen_str=A!%~1!" &:: keep the A up front to ensure we get the length and not the upper bound
::it also avoids trouble in case of empty string
set "StrLen_len=0"
for /L %%A in (12,-1,0) do (
set /a "StrLen_len|=1<<%%A"
for %%B in (!StrLen_len!) do if "!StrLen_str:~%%B,1!"=="" set /a "StrLen_len&=~1<<%%A"
)
IF "%~2" NEQ "" SET /a %~2=%StrLen_len%
#goto:eof
:End
echo(Bye
exit /b 0
Thanks to James K
The link you provided leads to the right answer:
There is no way to preserve an asterisk (nor a question mark) in the set of a normal (no /F option) FOR command (they are always changed to file names); you need to separate the parameters in a FOR /F command. If you also want to process each parameter in a FOR loop, then the second FOR can NOT be in the same context, so you must CALL a subroutine to change the context
If I know that one environment variable contains the name of another, how can I get the value of the second environment variable?
Assume I have a file java.properties alongside my batch file with the following contents.
JAVA_HOME_OVERRIDE_ENV_VAR=JAVA_HOME_1_7_0_17
What I want to do is check if JAVA_HOME_1_7_0_17 is set and, if so, do the equivalent of set JAVA_HOME=%JAVA_HOME_1_7_0_17%. I can figure out what environment variable I'm looking for, but I don't know how to get its value. This is what I have so far...
#echo off
setlocal enabledelayedexpansion
if exist %~dp0\java.properties (
echo "Found java properties."
for /F "tokens=1* usebackq delims==" %%A IN (%~dp0\java.properties) DO (
if "%%A"=="JAVA_HOME_OVERRIDE_ENV_VAR" set JAVA_HOME_OVERRIDE_ENV_VAR=%%B
)
if not [!JAVA_HOME_OVERRIDE_ENV_VAR!] == [] (
echo "Override var is !JAVA_HOME_OVERRIDE_ENV_VAR!"
REM This is where I'm stuck!!!
REM Assume JAVA_HOME_OVERRIDE_ENV_VAR is JAVA_HOME_1_7_0_17
)
)
endlocal & set JAVA_HOME=%JAVA_HOME%
What I want to do is check if the environment variable JAVA_HOME_1_7_0_17 exists and, if it does, use its value to set JAVA_HOME.
Updated
I think the nested if statements are making things more difficult then needed. I got rid of them and the following seems to work.
#echo off
setlocal enabledelayedexpansion
if not exist "%~dp0\java.properties" (
goto:EOF
)
for /F "tokens=1* usebackq delims==" %%A IN ("%~dp0\java.properties") DO (
if "%%A"=="JAVA_HOME_OVERRIDE_ENV_VAR" set JAVA_HOME_OVERRIDE_ENV_VAR=%%B
)
if [!JAVA_HOME_OVERRIDE_ENV_VAR!] == [] (
goto:EOF
)
set JAVA_HOME=!%JAVA_HOME_OVERRIDE_ENV_VAR%!
endlocal & set JAVA_HOME="%JAVA_HOME%"
Try set JAVA_HOME=%!JAVA_HOME_OVERRIDE_ENV_VAR!%.
EDIT: This should not work if !JAVA_HOME_OVERRIDE_ENV_VAR! was set on the same line. Try
call set JAVA_HOME=!%JAVA_HOME_OVERRIDE_ENV_VAR%!
a downside being that since it will search the disk for a file/executable with the name set, the command should take slightly longer to finish, though it should only be noticeable in large loops.
EDIT 2: Try this too...
(add set override=0 in front, add set override=1 under if not, and replace the endlocal line)
#echo off
setlocal enabledelayedexpansion
set override=0
if exist %~dp0\java.properties (
echo "Found java properties."
for /F "tokens=1* usebackq delims==" %%A IN (%~dp0\java.properties) DO (
if "%%A"=="JAVA_HOME_OVERRIDE_ENV_VAR" set JAVA_HOME_OVERRIDE_ENV_VAR=%%B
)
if not [!JAVA_HOME_OVERRIDE_ENV_VAR!] == [] (
echo "Override var is !JAVA_HOME_OVERRIDE_ENV_VAR!"
set override=1
REM Assume JAVA_HOME_OVERRIDE_ENV_VAR is JAVA_HOME_1_7_0_17
)
)
endlocal & if override=1 set JAVA_HOME=!%JAVA_HOME_OVERRIDE_ENV_VAR%!
I would use FINDSTR to filter out the relevant line, IF DEFINED to validate the existence of the variable, and delayed expansion within the loop to get the appropriate value.
Your code could be as simple as:
#echo off
setlocal enableDelayedExpansion
for /f "tokens=1* delims==" %%A in (
'2^>nul findstr /bil "JAVA_HOME_OVERRIDE_ENV_VAR=" "%~dp0\java.properties"'
) do if defined %%B set "JAVA_HOME=!%%B!"
endlocal & set "JAVA_HOME=%JAVA_HOME%"