How to read from a .properties file using batch script - windows

I have a requirement where i'd like to read values from a .properties file
my properties file test.properties content
file=jaguar8
extension=txt
path=c:\Program Files\AC
From the above file I need to fetch jaguar or anything after =
Please help me. Thanks

For /F "tokens=1* delims==" %%A IN (test.properties) DO (
IF "%%A"=="file" set file=%%B
)
echo "%file%"
hope this could help

#echo off
FOR /F "tokens=1,2 delims==" %%G IN (test.properties) DO (set %%G=%%H)
echo %file%
echo %extension%
echo %path%
Note that there is no space after %%H. Else this causes a space to be appended, to file paths for example, and will cause file not found errors when the variables from the property files are used as part of a file path.Struggled for hours because of this!

A solution with support for comments (# style). See comments in code for explanation.
test.properties:
# some comment with = char, empty line below
#invalid.property=1
some.property=2
some.property=3
# not sure if this is supported by .properties syntax
text=asd=f
properties-read.bat:
#echo off
rem eol stops comments from being parsed
rem otherwise split lines at the = char into two tokens
for /F "eol=# delims== tokens=1,*" %%a in (test.properties) do (
rem proper lines have both a and b set
rem if okay, assign property to some kind of namespace
rem so some.property becomes test.some.property in batch-land
if NOT "%%a"=="" if NOT "%%b"=="" set test.%%a=%%b
)
rem debug namespace test.
set test.
rem do something useful with your vars
rem cleanup namespace test.
rem nul redirection stops error output if no test. var is set
for /F "tokens=1 delims==" %%v in ('set test. 2^>nul') do (
set %%v=
)
output from set test. (see above):
test.some.property=3
test.text=asd=f
The most important parts are:
the for-loop with the eol and delims option and
the if-checks that both variables %%a and %%b are set.
What you do in the for-loop with the variable and its value is certainly up to you - assigning to some prefixed variables was just an example. The namespacing approach avoids that any other global variable gets overridden.
For example if you have something like appdata defined in your .properties file.
I'm using this to get rid of an extra config.bat and instead using one .properties file for both the java app and some support batch files.
Works for me, but certainly not every edge case is covered here, so improvements welcome!

Try this
echo off
setlocal
FOR /F "tokens=3,* delims=.=" %%G IN (test.properties) DO ( set %%G=%%H )
rem now use below vars
if "%%G"=="file"
set lfile=%%H
if "%%G"=="path"
set lpath=%%H
if "%%G"=="extension"
set lextention=%%H
echo %path%
endlocal

I know this is ancient post but I would like to expand on toschug's great answer.
If the path in the .properties file would be defined as %~dp0 or any other variable that needs to be expanded first before using it, I recommend doing it the following way:
In the .properties file:
path=%~dp0
In the batch file you can then use it the following way (the code is to be used between the two for(s) defining one <=> cleanup one):
if "!test.path!" NEQ "" (
echo Not expanded path: !test.path!
call :expand !test.path! test.path
)
echo test.path expanded: !test.path!
pause
:expand
SET "%~2=%~1"
GOTO :EOF
Don't forget to use (at the start of the batch file):
SETLOCAL ENABLEDELAYEDEXPANSION

you can try this:
#ECHO OFF
#SETLOCAL
FOR /F "tokens=1* delims==" %%A IN (test.properties) DO (
ECHO %%A = %%B
)
#ENDLOCAL

Related

How to use nested FOR loops in batch files

I have some code in which I want to use a FOR loop to handle a set of files.
As part of handling a file there's a FOR /F loop that reads it and appends data to an other file based on the file name.
In order to be able to set the output file name I have delayed variable expansion set on.
This is what the code should look like as I originally intended it to be:
setlocal enabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
set POI=%%~f
set POI=!JbPOI:DataFolder\=!
set POI=!JbPOI:.Ext=!
for /f "tokens=1,2,3 delims=," %%a in ("%%~f") do (
set CX=%%a
set CY=%%b
set FN=%%c
echo !FN!,9,!CX!,!CY! >> "DataFolder\!POI!.tmp"
)
)
endlocal
This code doesn't work because variable %%a, %%b and %%c never receive a value, %%a always has the same value as %%f.
I have read some articles about this issue but couldn't extract a solution from them that worked.
I have tried several things, none worked so far...
added a dummy outer loop to create variable %%a through %%j explicitly
inner FOR loop taken out and made it a subroutine
inner FOR loop taken out and made it a separate batch file
Can anybody please tell me how this can - or must - be solved?
setlocal enabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
set POI=%%~f
set POI=!JbPOI:DataFolder\=!
set POI=!JbPOI:.Ext=!
for /f "useback tokens=1,2,3 delims=," %%a in ("%%~f") do (
set CX=%%a
set CY=%%b
set FN=%%c
echo !FN!,9,!CX!,!CY! >> "DataFolder\!POI!.tmp"
)
)
endlocal
I'm not sure if you want to read the file "%%~f" , but I think this is what you need.
Sorry, but for the posted code i don't see the need for delayed expansion. All the needed data is being directly retrieved from the for replaceable parameters
setlocal enableextensions disabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
(
for /f "usebackq tokens=1-3 delims=," %%a in ("%%~f") do echo(%%c,9,%%a,%%b
) > "DataFolder\%%~nf.tmp"
)
endlocal
If the real code includes something not posted, maybe the answer from npocmaka will better fit in the problem.

remove all double quotes in a file.txt

What I have to do is a batch script that:
_read a file line by line
_remove all the double quote characters writing the result in a file
My attempt was a script like:
for /f "usebackq tokens=*" %%a in ("%GRUPPI3%.txt") do (
SET VARIAB=%%a
SET RESULT=%VARIAB:"=%
echo %RESULT% >> output.txt
)
After some try I realized that the PROBLEM IS THE VARIABLE "VARIAB"!
Doing an echo of VARIAB the result is null or an old value (like an old line read by the variable %%a). (Why "VARIAB" doesn't become a copy of "%%a" as I would expect?)
I can't understand such a behaviour...
Someone know the solution?
Thanks
Cristian
#ECHO OFF
SETLOCAL
(
for /f "usebackq tokens=*" %%a in ("%GRUPPI3%.txt") do (
SET "VARIAB=%%a"
IF DEFINED variab (
SETLOCAL enabledelayedexpansion
SET "RESULT=!VARIAB:"=!"
ECHO(!RESULT!
ENDLOCAL
)
)
)>newfile.txt
GOTO :EOF
This should fix your problem. I changed the detination file to suit my system. If you want to append to the destination file, use >> in place of >

Store Multiline String in Batch Variable

I need to remove a string that may occur inside a file. The string has many lines. Can I perform this action using a Batch script?
I've heard that you cant have variables with more than one line in Batch? The string will come from another file that I will read into a variable using Batch.
The following code seems to only store the 1st/last line of a file in the string?? Whats going wrong?
Rem Read file and store all contents in string
Set replace=
Set target=
Set OUTFILE=res.txt
for /f "delims=" %%i in (myFile.txt) do set target=%target% %%i
echo %target%
Rem When I print target I only have one line not many lines?? Whats going wrong
Rem Remove the target string from myOtherFile.txt: this code is from http://stackoverflow.com/questions/5273937/how-to-replace-substrings-in-windows-batch-file
for /f "tokens=1,* delims=ΒΆ" %%A in ( '"type myOtherFile.txt"') do (
SET string=%%A
SET modified=!string:%target%=%replace%!
echo !modified! >> %OUTFILE%
)
Try this:
#echo off &setlocal enabledelayedexpansion
for /f "delims=" %%i in (myFile.txt) do set "target=!target! %%i"
echo %target%
Inside a code block you need always delayed expansion for variables with variable values.
Try this, change last to:
echo !target!

Get string from file in batch

Task in CMD.
1) How can I compare if string is in string? I checked manual here for "Boolean Test "does string exist ?"" But I can't understand the example or it does not work for me. This piece of code, it is just a try. I try to make a string compare of filter some sting if there is a tag <a> in a line.
FOR /f "tokens=* delims= usebackq" %%c in ("%source%") DO (
echo %%c
IF %%c == "<a" (pause)
)
So while I read a file, it should be paused if there is a link on a line.
2) I have one more ask. I would need to filter the line if there is a specific file in the link, and get content of the link. My original idea was to try to use findstr with regex, but it seems not to use sub-patterns. And next problem would be how to get the result to variable.
set "pdf=0_1_en.pdf"
type "%source%" | grep "%pdf%" | findstr /r /c:"%pdf%.*>(.*).*</a>"
So in summary, I want to go through file and if there is a link like this: REPAIRED: *
<b>GEN 0.1 Preface</b>
I forgot to style this as a code, so the inside of code was not displayed. Sorry.
Warnning: we don't know the path, only the basic filename.
Get the title GEN 0.1 Preface. But you should know, that there are also similar links with same link, which contain image, not a text inside a tag.
Code according Aacini to be changed a little bit:
#echo off
setlocal EnableDelayedExpansion
set "source=GEN 0 GENERAL.html"
set "pdf=0_1_en.pdf"
echo In file:%source%
echo Look for anchor:%pdf%
rem Process each line in %source% file:
for /F "usebackq delims=" %%c in ("%source%") do (
set "line=%%c"
rem Test if the line contain a "tag" that start with "<a" string:
set "tag=!line:*<a=!"
if not "!tag!" == "!line!" (
rem Take the string in tag that end in ">"
for /F "delims=^>" %%a in ("!tag!") do set "link=%%a"
echo Link found: !link!
if "!link!" == "GEN 0.1 Preface" echo Seeked link found
)
)
pause
Still not finished
Although your question is extensive it does not provide to much details, so I assumed several points because I don't know too much about .PDF files, tags, etc.
#echo off
setlocal EnableDelayedExpansion
set "source=GEN 0 GENERAL.html"
set "pdf=0_1_en.pdf"
echo In file: "%source%"
echo Look for anchor: "%pdf%"
rem Process each line in %source% file:
for /F "usebackq delims=" %%c in ("%source%") do (
set "line=%%c"
rem Test if the line contain "<a>" tag:
set "tag=!line:*<a>=!"
if not "!tag!" == "!line!" (
rem Test if "<a>" tag contain the anchor pdf file:
if not "!tag:%pdf%=!" == "!tag!" (
rem Get the value of "<b>" sub-tag
set "tag=!tag:<b>=$!"
set "tag=!tag:</b>=$!"
for /F "tokens=2 delims=$" %%b in ("!tag!") do set title=%%b
echo Title found: "!title!"
)
)
)
pause
Any missing point can be added or fixed, if you give me precise details about them.
EDIT: I fixed the program above after last indications from the OP. I used $ character to get the Title value; if this character may exist in original Tag, it must be changed by another unused one.
I tested this program with this "GEN 0 GENERAL.html" example file:
Line one
<a>href="/Dokumenter/EK_GEN_0_X_en.pdf" class="uline"><b>GEN 0.X Preface</b></a>
Line three
<a>href="/Dokumenter/EK_GEN_0_1_en.pdf" class="uline"><b>GEN 0.1 Preface</b></a>
Line five
and get this result:
In file: "GEN 0 GENERAL.html"
Look for anchor: "0_1_en.pdf"
Title found: "GEN 0.1 Preface"
EDIT: New faster method added
There is a simpler and faster method to solve this problem that, however, may fail if a line contains more than one tag:
#echo off
setlocal EnableDelayedExpansion
set "source=GEN 0 GENERAL.html"
set "pdf=0_1_en.pdf"
echo In file: "%source%"
echo Look for anchor: "%pdf%"
for /F "delims=" %%c in ('findstr /C:"<a>" "%source%" ^| findstr /C:"%pdf%"') do (
set "tag=%%c"
rem Get the value of "<b>" sub-tag
set "tag=!tag:<b>=$!"
set "tag=!tag:</b>=$!"
for /F "tokens=2 delims=$" %%b in ("!tag!") do set title=%%b
echo Title found: "!title!"
)
pause
First, one important question: does this really have to be implemented via a CMD script? Would you be able to go with VBScript, PowerShell, C#, or some other scripting/programming language? CMD is a notoriously painful scripting environment.
Secondly, I'm not sure if this answers your question--it's a bit unclear--but here's a quick trick you can use to see in CMD to see if a given string contains another substring:
setlocal enableextensions enabledelayedexpansion
set PATTERN=somepattern
for /f "delims=" %%f in (somefile.txt) do (
set CURRENT_LINE=%%f
if "!CURRENT_LINE:%PATTERN%=!" neq "!TEMP!" (
echo Found pattern in line: %%f
)
)
The idea is that you try to perform string replacement and see if anything was changed. This is certainly a hack, and it would be preferable if you could instead use a tool like findstr or grep, but if you're limited in your options, something like the above should work.
NOTE: I haven't actually run the above script excerpt, so let me know if you have any difficulty with it.
I have modified the way to do it. I realized that it is better to find name of pdf document first. This is my almost completed solution, but I ask you if you could help me with the last point. The last replacing statement does not work because I need to remove closing tag b. Just to get the title.
#echo off
setlocal EnableDelayedExpansion
set "source=GEN 0 GENERAL.html"
set "pdf=0_1_en.pdf"
echo In file:%source%
echo Look for anchor:%pdf%
rem Process each line in %source% file:
for /F "usebackq delims=" %%c in ("%source%") do (
set "line=%%c"
REM Test if the line contains pdf file I look for:
SET "pdfline=!line:%pdf%=!"
if not "!pdfline!" == "!line!" (
cls
echo Line: !line!
REM Test if the pdfline contains tag b
SET "tagline=!pdfline:*><b>=!"
if not "!tagline!" == "!pdfline!" (
cls
echo ACTUAL LINE: !tagline!
REM Remove closing tag b
SET "title=!tagline:</b*=!"
echo TITLE: !title!
pause
)
)
)
pause
BTW:
The html page I work with is here.
So I ask you to help complete/repair line SET "title=!tagline:</b*=!"

batch find file extension

If I am iterating over each file using :
#echo off
FOR %%f IN (*\*.\**) DO (
echo %%f
)
how could I print the extension of each file? I tried assigning %%f to a temporary variable, and then using the code : echo "%t:~-3%" to print but with no success.
The FOR command has several built-in switches that allow you to modify file names. Try the following:
#echo off
for %%i in (*.*) do echo "%%~xi"
For further details, use help for to get a complete list of the modifiers - there are quite a few!
This works, although it's not blindingly fast:
#echo off
for %%f in (*.*) do call :procfile %%f
goto :eof
:procfile
set fname=%1
set ename=
:loop1
if "%fname%"=="" (
set ename=
goto :exit1
)
if not "%fname:~-1%"=="." (
set ename=%fname:~-1%%ename%
set fname=%fname:~0,-1%
goto :loop1
)
:exit1
echo.%ename%
goto :eof
Sam's answer is definitely the easiest for what you want. But I wanted to add:
Don't set a variable inside the ()'s of a for and expect to use it right away, unless you have previously issued
setlocal ENABLEDELAYEDEXPANSION
and you are using ! instead of % to wrap the variable name. For instance,
#echo off
setlocal ENABLEDELAYEDEXPANSION
FOR %%f IN (*.*) DO (
set t=%%f
echo !t:~-3!
)
Check out
set /?
for more info.
The other alternative is to call a subroutine to do the set, like Pax shows.

Resources