3

I am referring to below threat Batch files: How to read a file?. For retrieving the line by line from a text file. I am using the below script:

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo !var!
    ENDLOCAL
)

Code is working fine! The values in !var! can not assign to any variable. :( I struct there, Please anyone help to read line by line and I wish to assign to some variable and want to manipulate that variable. Please help to solve this situation.

Update:

@ECHO off

CLS

SET PROJ_DIR=D:\workspace\proj
SET PROMO_DIR=D:\TEST
SET SOURCE_CODE=\Source Code

SETLOCAL DisableDelayedExpansion
for /f %%a in (paths.txt) do (
    SET "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    set FILE_PATH=!var://www.domain.com/path/dir=!
    SET FILE_PATH=!FILE_PATH:/=\!
    SET PROMO_FILE_PATH=!PROMO_DIR!!SOURCE_CODE!!FILE_PATH! 
    FOR %%i IN ("!PROMO_FILE_PATH!") DO SET FOLDER_PATH=%%~dpi
    FOR %%i IN ("!PROMO_FILE_PATH!") DO SET FILE_NAME=%%~nxi
    IF EXIST "!FOLDER_PATH!" GOTO F3
        MKDIR "!FOLDER_PATH!"
    :F3
    IF NOT EXIST "!PROJ_DIR!!FILE_PATH!" GOTO F4
        COPY "!PROJ_DIR!!FILE_PATH!" "!FOLDER_PATH!"
    :F4
        ECHO Cannot find the file under "!PROJ_DIR!!FILE_PATH!"

    ENDLOCAL
)

SET CLOSE_CONFIRM=
SET /P CLOSE_CONFIRM=Press any key to close the window...%=%

paths.txt

//www.domain.com/path/dir/dir1/dir2/file1.txt 
//www.domain.com/path/dir/dir1/dir2/file2.txt 
//www.domain.com/path/dir/dir1/dir2/file3.txt 
//www.domain.com/path/dir/dir1/dir2/file4.txt 
//www.domain.com/path/dir/dir1/dir3/file1.txt

Command Output

        1 file(s) copied.
Cannot find the file under "D:\workspace\proj\dir1\dir2\file1.txt"
        1 file(s) copied.
Cannot find the file under "D:\workspace\proj\dir1\dir2\file2.txt"
Press any key to close the window...

thanks..

6
  • 1
    A simple set "myVar2=!var!" should work, or do you try to access the variable after the endlocal? Commented Jun 8, 2011 at 12:36
  • It does't work for me :( i tried "myvar2=!var!" and then echo %myvar2%. But, it is not printing anything. It simply prints ECHO is on. What can I do? please help on this. thanks Commented Jun 8, 2011 at 14:46
  • The assignment works, but your echo fails, as percent expansion is done only once BEFORE the Loop is executed. Change it to echo !myvar2! Commented Jun 8, 2011 at 17:29
  • You should show the input file and/or add some debug outputs into your code like echo !var! !FILE_PATH! Commented Jun 9, 2011 at 10:02
  • well, I got the issue. I hope you can understand my piece of code. The problem is that when a particular folder has more than 2 files. It can copy only two files and then terminating the process. that is the problem with my code. why is that happening? Commented Jun 9, 2011 at 10:06

4 Answers 4

2

The key is the delayed expansion, expand your variables inside of parenthesis always with ! not with %.

A sample that changes X with Y

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    set "myVar=!var!"
    set "myVar=!myVar:X=Y!"
    echo X replaced with Y =!myVar! 
    ENDLOCAL
)

In your updated version the goto :label stops the for-loop immediatly

Better rewrite it to IF-Blocks

IF NOT EXIST "!FOLDER_PATH!" (
  MKDIR "!FOLDER_PATH!"
)
IF EXIST "!PROJ_DIR!!FILE_PATH!" (
    COPY "!PROJ_DIR!!FILE_PATH!" "!FOLDER_PATH!"
) ELSE
(
    ECHO Cannot find the file under "!PROJ_DIR!!FILE_PATH!"
)
Sign up to request clarification or add additional context in comments.

3 Comments

Hi jeb, thanks thats works for me :) but another problem. It reads 2 lines out of 5 lines from the file. :( why is it so?
hi jeb, now updated! please look into the question... thanks, it is not reading all the lines in a file. why so?
many thanks man! actually, there was logical mistake.. now working :))
2

The other answers here cover the tricky bits of delayed expansion in this code. I want to add that you can often avoid most delayed expansion problems by rolling the parentheses out into a subroutine.

FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do call :HandlePath %%a
goto :eof

================
:HandlePath
set "var=%*"
set "var=%var:*:=%"
echo %var%
goto :eof

I find this code easier to maintain because each line is parsed an executed exactly when you would expect.

1 Comment

+1, Good hint for simple problems, but this will fail dependent on the line contents, you can not handle lines like A difficult text "&"& with percent expansion nor with calling parameters
1

If you want to read each line and manipulate it:

SETLOCAL EnableDelayedExpansion
FOR /F "tokens=*" %%a IN (paths.txt) DO (
set var=%%a
ECHO %var%
PAUSE
)
ENDLOCAL

If you are trying to search a string from a file and manipulate it:

SETLOCAL EnableDelayedExpansion
FOR /F "tokens=* usebackq" %%a IN (`FIND /I 'string to search for' "C:\folder\paths.txt"`) DO (
set var=%%a
ECHO %var%
PAUSE
)
ENDLOCAL

If you are trying to search a string and manipulate each word in the string:

SETLOCAL EnableDelayedExpansion
FOR /F "usebackq tokens=1-999 delims= " %%a IN (`FIND /I 'string to search for' "C:\folder\paths.txt"`) DO (
REM %%a = first word  %%b = second word etc. through the alphabet
set var1=%%a%%b%%c
set var2=%%d
ser var3=%%e
ECHO %var1% %var2% %var3%
PAUSE
)
ENDLOCAL

4 Comments

It just prints ECHO is off. I cant assign like var2=!var!.
and a quick question... are you trying to search for specific strings in the text file or you want all lines to be read? And I've never seen !var:*:=! used before... what does :*:= supposed to do to the variable?
thanks for your prompt response, well I am trying to read line by line from a file and I just want to manipulate that line... this is what I want to achieve...
Your echo's can't work as the %var1% %var2% expands BEFORE the loop starts, you need here delayed expansion or the call technic (very slow)
0

This works for me:

@echo off
SETLOCAL EnableDelayedExpansion

FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
set var=%%a
set var=!var:*:=!
echo !var!
)
ENDLOCAL

1 Comment

I introduced the delayed toggling technic, as in your code you will lose all ! and sometimes also the ^

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.