# Solved: DOS - File Read for environment variables



## trusp (Dec 5, 2008)

Using Batch file(.bat Dos based)
I have to read a text file(temp.txt) containing data as the following:

#,User,Password,Feed,Capacity
Trusp,doit123,DNR,25
#,Thamba,ert23,IRR,30
#,Andrew,,,,

Using batch file I have to read the contents of the file and have to set variables as

User=Trusp
Pass=doit123
Feed=DNR
Capacity=25


So for executing this script the user has to simply edit the values in temp.txt

This is the script I created for this function 
for /f "eol=; tokens=1-4 delims=," %%i in ("temp.txt") do (
if NOT %%i==#(
set User=%%i
set Pass=%%j
set Feed=%%k
set Capacity=%%l
)
)

Here I need to read the text file and set the environment variables.
So please help me out in this issue.


----------



## trusp (Dec 5, 2008)

Hi I modified the script as below

for /f "usebackq eol= tokens=* delims= " %%i in ("temp.txt") do (
set STL_INFO=%%i
for /f "usebackq eol= tokens=* delims=, " %%a in (%STL_INFO%) do (
if NOT %%a=='#'(
set User=%%a
set Pass=%%b
set Feed=%%c
set Capacity=%%d
------
------
)
)
)

But still I could not get a solution. 
Can any one help me out in this issue ???? 

Trusp


----------



## trusp (Dec 5, 2008)

I can access when I use %%a.
But I cant assign the value to a variable and access the values.
Using like this : set User=%%a 
set Pass=%%b
Is it a wrong solution.

This is the script I am using:
for /f "usebackq eol= tokens=* delims= " %%i in ("temp.txt") do (
for /f "usebackq eol= tokens=1-5 delims=, " %%a in ('%%i') do ( 
if NOT %%a==# (
echo ---------------
echo %%a
echo %%b 
echo %%c
echo %%d
echo ---------------
set User=%%a
set Pass=%%b
set Feed=%%c
set Capacity=%%d
echo ---------------
echo %user%
echo %pass%
echo %Feed%
echo %Capacity%
echo --------------- 
) 
)
) 

Thanks.

Trusp


----------



## TheOutcaste (Aug 8, 2007)

trusp said:


> for /f "eol=; tokens=1-4 delims=," %%i in ("temp.txt") do (
> if NOT %%i==#(


As *temp.txt* is in quotes, it is seen as a literal string, not a file name, so you get %%i=temp.txt, not each line in temp.txt, and therefore no j,k,or l variables
There is no space before the "*(*" so that can cause an error.

Remove the quotes and add the space, and it works fine. If the actual path/file name for *temp.txt* includes spaces, use the *usebackq* option



trusp said:


> for /f "usebackq eol= tokens=* delims= " %%i in ("temp.txt") do (
> set STL_INFO=%%i
> for /f "usebackq eol= tokens=* delims=, " %%a in (%STL_INFO%) do (
> if NOT %%a=='#'(


As you haven't enabled Delayed Expansion, the second loop sees %STL_INFO% as whatever value it last had. So the first time this runs it works (after adding the space), but after that it will give errors.
And, there is no space before the "(" so that can cause an error.
So, adding the space, and adding a line *Set STL_INFO=* at the start will get this working.

Your third script works just fine for me. I modified it slightly to show which variable is being echoed:

```
@echo off
for /f "usebackq eol= tokens=* delims= " %%i in ("temp.txt") do (
for /f "usebackq eol= tokens=1-5 delims=, " %%a in ('%%i') do (
if NOT %%a==# (
echo ---------------
echo [COLOR=Red]Loop a is [/COLOR]%%a
echo [COLOR=Red]Loop b is [/COLOR]%%b
echo [COLOR=Red]Loop c is[/COLOR] %%c
echo [COLOR=Red]Loop d is[/COLOR] %%d
echo ---------------
set User=%%a
set Pass=%%b
set Feed=%%c
set Capacity=%%d
echo ---------------
echo [COLOR=Red]User is[/COLOR] %user%
echo [COLOR=Red]pass is[/COLOR] %pass%
echo [COLOR=Red]Feed is[/COLOR] %Feed%
echo [COLOR=Red]Capacity is[/COLOR] %Capacity%
echo ---------------
)
)
)
```
Output is:

```
C:\Scripts\tmp>test.cmd
---------------
Loop a is Trusp
Loop b is doit123
Loop c is DNR
Loop d is 25
---------------
---------------
User is Trusp
pass is doit123
Feed is DNR
Capacity is 25
---------------

C:\Scripts\tmp>
```
Your first code with the two corrections is the one to use:

```
@echo off
for /f "eol=; tokens=1-4 delims=," %%i in (temp.txt) do (
if NOT %%i==# (
set User=%%i
set Pass=%%j
set Feed=%%k
set Capacity=%%l
)
)
echo User is %user%
echo pass is %pass%
echo Feed is %Feed%
echo Capacity is %Capacity%
```
Output:

```
C:\Scripts\tmp>test.cmd
User is Trusp
pass is doit123
Feed is DNR
Capacity is 25

C:\Scripts\tmp>
```
HTH

Jerry


----------



## trusp (Dec 5, 2008)

Thanks Jerry.

Can u tell what the difference between your code and the following:
for /f "eol=# tokens=1-4 delims=," %%i in ("temp.txt") do (
)

Because this also produce the correct result.
So please tell me which may be the best.

Trusp


----------



## trusp (Dec 5, 2008)

The Text file(temp.txt) each line ends with "," as below:

#,User,Password,Feed,Capacity,
Trusp,doit123,DNR,25,
#,Thamba,ert23,IRR,30,
#,Andrew,,,,

So I got this doubt ?

for /f "eol=# tokens=1-4 delims=," %%i in ("temp.txt") do (
)

or 

for /f "eol=; tokens=1-4 delims=," %%i in (temp.txt) do (
if NOT %%i==# (
))

Which may be the applicable one. Please help me out

Trusp


----------



## TheOutcaste (Aug 8, 2007)

trusp said:


> Thanks Jerry.
> 
> Can u tell what the difference between your code and the following:
> for /f "eol=# tokens=1-4 delims=," %%i in ("temp.txt") do (
> ...


Your code with the double quotes will see temp.txt as a string to process, so %%i will be set to temp.txt, not anything in the file. It will not produce the correct result.
You are not using local variables, so once the variables are set, they will remain with the last value until they are changed. The code using double quotes won't change them, so it may *APPEAR* that it is working, as it's displaying the values the variables had BEFORE the file is run. You can test this by typing *Set User=this is not valid* at the prompt, then run the file. If you have double quotes around temp.txt, *User* will not be changed

Add this line to clear those variables before each run to eliminate that:

```
For %%I In (User Pass Feed Capacity) do Set %%I=
```
Add any other variable names to be cleared
Or, add a *Setlocal* statement to the start of your file. *Close, then open a new command prompt to clear any current variables*.
With this method, you can't check the variables after the file ends though, so I recommend the first method while testing.



trusp said:


> The Text file(temp.txt) each line ends with "," as below:
> 
> #,User,Password,Feed,Capacity,
> Trusp,doit123,DNR,25,
> ...


The comma on the end won't make any difference. You are only using 4 tokens, and that comma is at the end of the 4th item on the line you want, and after the 5th item on the rest
The first will fail because you have the quotes.
Using the # as the EOL character though means you don't actually need the If statement, so remove the quotes and the If statement.
The second one will work. If temp.txt is very large, it may be slower because of the IF statement though.

This is what I would use:

```
@echo off
For %%I in (User pass feed Capacity) do Set %%I=
Set _FileName=temp.txt
For /f "usebackq eol=# tokens=1-4 delims=," %%a In ("%_FileName%") Do (
set User=%%a
set Pass=%%b
set Feed=%%c
set Capacity=%%d
)
echo User is %user%
echo pass is %pass%
echo Feed is %Feed%
echo Capacity is %Capacity%
```
By using a variable for the file name it makes it easier to change if needed. By using the usebackq option and putting the variable in double quotes, you don't have to worry about someone trying to use a file that has spaces in the path or name.

Here's the help section from FOR /? for the /F option and using the *usebackq* option. I've shown the 8 possible combinations and the results. Hopefully that will help explain how the various quotes affect the results

From For /?:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN (*"*string*"*) DO command [command-parameters]
FOR /F ["options"] %variable IN (*'*command*'*) DO command [command-parameters]

or, if usebackq option present:

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN (*'*string*'*) DO command [command-parameters]
FOR /F ["options"] %variable IN (*`*command*`*) DO command [command-parameters]

So there are 8 possibilities depending on if the usebackq option is present, and if you use no quotes, a single quote (*'*), a double quote (*"*) or a back quote (*`*):


for /f "eol=# tokens=1-4 delims=," %%a in (temp.txt) do
for /f "eol=# tokens=1-4 delims=," %%a in (*"*temp.txt*"*) do
for /f "eol=# tokens=1-4 delims=," %%a in (*`*temp.txt*`*) do
for /f "eol=# tokens=1-4 delims=," %%a in (*'*temp.txt*'*) do
for /f "usebackq eol=# tokens=1-4 delims=," %%a in (temp.txt) do
for /f "usebackq eol=# tokens=1-4 delims=," %%a in (*"*temp.txt*"*) do
for /f "usebackq eol=# tokens=1-4 delims=," %%a in (*'*temp.txt*'*) do
for /f "usebackq eol=# tokens=1-4 delims=," %%a in (*`*temp.txt*`*) do
These are the results:

temp.txt is a *file* that will be processed (cannot have spaces)
temp.txt is read and the loop variable(s) are set to the contents of the file
temp.txt is a *string* that will be processed (can have spaces)
The loop variable %%a is set to temp.txt
temp.txt is a *command* that will be processed
Opens temp.txt in Notepad
*`*temp.txt*`* is a *file* that will be processed (cannot have spaces)
Invalid, will cause an error *The system cannot find the file `temp.txt`. *as it's looking for a file name starting with a back quote
temp.txt is a *file* that will be processed (cannot have spaces)
temp.txt is read and the loop variable(s) are set to the contents of the file
temp.txt is a *file* that will be processed (can have spaces)
temp.txt is read and the loop variable(s) are set to the contents of the file
temp.txt is a *string* that will be processed (can have spaces)
The loop variable %%a is set to temp.txt
temp.txt is a *command* that will be processed
Opens temp.txt in Notepad

HTH

Jerry


----------



## trusp (Dec 5, 2008)

Jerry, Thank you very much for your patience in explaining me in detail.

I executed both the queries. And it works fine if there is only 1 line uncommented in text file("Temp.txt"). 
If there are more than 1 line uncommented then the last uncommented value is displayed.

temp.txt is found as follows:
#,User,Password,Feed,Capacity
Trusp,doit123,DNR,25
Jacob,cccer2,IRN,5
Bruno,dfsg43,TRE,24
#,Thamba,ert23,IRR,30
#,Andrew,,,,

Result: 
User is Bruno
pass is dfsg43
Feed is TRE
Capacity is 24
(These values were repeated thrice)

So please find whether anything to be modified to get the correct result.
Thanks. Help me out in this issue asap.

Trusp


----------



## TheOutcaste (Aug 8, 2007)

trusp said:


> Jerry, Thank you very much for your patience in explaining me in detail.
> 
> I executed both the queries. And it works fine if there is only 1 line uncommented in text file("Temp.txt").
> If there are more than 1 line uncommented then the last uncommented value is displayed.


That is what it should do. If you need to have multiple lines uncommented, and then do something for each entry, then you just need to add the code to process each line _inside_ the loop. And doing that means you will need to use Delayed Expansion


```
@echo off
For %%I in (User pass feed Capacity) do Set %%I=
Set _FileName=temp.txt[COLOR=Red][B]
Setlocal EnableDelayedExpansion[/B][/COLOR]
For /f "usebackq eol=# tokens=1-4 delims=," %%a In ("%_FileName%") Do (
set User=%%a
set Pass=%%b
set Feed=%%c
set Capacity=%%d
:: Processing code goes here
echo Current values: User=[COLOR=Red][B]![/B][/COLOR]user[COLOR=Red][B]![/B][/COLOR], Pass=[COLOR=Red][B]![/B][/COLOR]Pass[COLOR=Red][B]![/B][/COLOR], Feed=[COLOR=Red][B]![/B][/COLOR]Feed[COLOR=Red][B]![/B][/COLOR], Capacity=[COLOR=Red][B]![/B][/COLOR]Capacity[COLOR=Red][B]![/B][/COLOR]
)
Endlocal
```
Note that inside the loop, you must use the *!* symbol instead of the *%* symbol.
When the loop ends, the variables will have the value of the last line that did not have #, and will be deleted when the file ends (or you hit the Endlocal statement).

HTH

Jerry


----------



## trusp (Dec 5, 2008)

Jerry Thank you very much. Its working fine on using Delayed Expansion.

Trusp


----------



## TheOutcaste (Aug 8, 2007)

You're welcome!

Jerry


----------

