Use of FOR in a batch file
Moderator: DosItHelp
Use of FOR in a batch file
Hi
I have 2 directories with the same files and I want to compare them using fc.exe. I do not quite understand how the "for...in...do" works.
I would also like to take advantage of fc's errorlevels if a file is not found for example.
I know how to redirect the dir command to create a list of the files I want to compare.
Thanks
I have 2 directories with the same files and I want to compare them using fc.exe. I do not quite understand how the "for...in...do" works.
I would also like to take advantage of fc's errorlevels if a file is not found for example.
I know how to redirect the dir command to create a list of the files I want to compare.
Thanks
Re: Use of FOR in a batch file
Code: Select all
@echo off
set d1=c:\test1
set d2=d:\test2
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
call set "$i=%%$i:%%i=%%"
if defined $i (
if not exist "%d1%\%%i" (echo :. +: %%i) else (
if not exist "%d2%\%%i" (echo :+ .: %%i) else (
fc "%d1%\%%i" "%d2%\%%i" >nul&& echo := =: %%i|| echo :^< ^>: %%i)))
set "$i=%%i"
)
P.S. files w/o subfolders
Use of FOR in a batch file
Cool!!!!
Even better than the one I had in mind! Very creative!
I have to learn this stuff. What's a good place to go?
PS. What if I want nothing displayed when files are equal?
Thanks again
Even better than the one I had in mind! Very creative!
I have to learn this stuff. What's a good place to go?
PS. What if I want nothing displayed when files are equal?
Thanks again
Re: Use of FOR in a batch file
may be here and heredrgt wrote:I have to learn this stuff. What's a good place to go?
delete from fc command line positive (&&) alternativedrgt wrote:What if I want nothing displayed when files are equal?
another method via enabledelayedexpansion, and w/o equal files:
Code: Select all
@echo off
setlocal enabledelayedexpansion
set d1=c:\in
set d2=d:\out
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
if /i not "!$i!"=="%%i" (
if not exist "%d1%\%%i" (echo :. +: %%i) else (
if not exist "%d2%\%%i" (echo :+ .: %%i) else (
fc "%d1%\%%i" "%d2%\%%i" >nul|| echo :^< ^>: %%i)))
set "$i=%%i"
)
P.S. file names must not contains "!" symbol
Re: Use of FOR in a batch file
amel27 wrote:P.S. file names must not contains "!" symbol
File names can contains also "!" symbols, if you change the code a little bit.
Code: Select all
@echo off
setlocal enabledelayedexpansion
set d1=c:\in
set d2=d:\out
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
setlocal Disabledelayedexpansion
set "fName=%%i"
setlocal enabledelayedexpansion
if /i not "!$i!"=="!fName!" (
if not exist "%d1%\!fName!" (echo :. +: !fName!) else (
if not exist "%d2%\!fName!" (echo :+ .: !fName!) else (
fc "%d1%\!fName!" "%d2%\!fName!" >nul || echo :^< ^>: !fName!)))
set "$i=!fName!"
)
jeb
Re: Use of FOR in a batch file
no! such code lead to an error:
SetLocal/EndLocal must each be paired with a matching end, especially in loop:
Maximum setlocal recursion level reached.
SetLocal/EndLocal must each be paired with a matching end, especially in loop:
Code: Select all
@echo off
SetLocal DisableDelayedExpansion
set d1=c:\test1
set d2=d:\test2
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
set "$f=%%i"& SetLocal EnableDelayedExpansion
if /i not "!$i!"=="!$f!" (
if not exist "%d1%\!$f!" (echo :. +: !$f!) else (
if not exist "%d2%\!$f!" (echo :+ .: !$f!) else (
fc "%d1%\!$f!" "%d2%\!$f!" >nul|| echo :^< ^>: !$f!)))
EndLocal& set "$i=%%i"
)
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: Use of FOR in a batch file
Good info jeb and amel27!
Re: Use of FOR in a batch file
amel27 wrote:no! such code lead to an error:
Yes, you got me, i didn't test it.
It only works with a few number of lines.
And of course it's really bad style to use setlocal without endlocal.
jeb
Use of FOR in a batch file
Hi Amel27,
Why if run for 2nd time it behaves differently? see below:
-----------------------------------
C:\>fico
-----
:1 2:
-----
:= =: New Text Document.txt
C:\>fico
-----
:1 2:
-----
C:\>
-------------------------------------
fico is the name of the file (fico.bat)
Why if run for 2nd time it behaves differently? see below:
-----------------------------------
C:\>fico
-----
:1 2:
-----
:= =: New Text Document.txt
C:\>fico
-----
:1 2:
-----
C:\>
-------------------------------------
fico is the name of the file (fico.bat)
Re: Use of FOR in a batch file
drgt wrote:Why if run for 2nd time it behaves differently?
sorry, but I can't verify you result, in my test results is identical
Use of FOR in a batch file
amel27 wrote:sorry, but I can't verify you result, in my test results is identical
How is it possible? Are we running the same code? My second run is as posted above.
Here is the code:
----------------------
@echo off
set d1=C:\Test\Comp1
set d2=C:\Test\Comp2
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
call set "$i=%%$i:%%i=%%"
if defined $i (
if not exist "%d1%\%%i" (echo :. +: %%i) else (
if not exist "%d2%\%%i" (echo :+ .: %%i) else (
fc "%d1%\%%i" "%d2%\%%i" >nul&& echo := =: %%i|| echo :^< ^>: %%i)))
set "$i=%%i"
)
------------------------
Please check again
Re: Use of FOR in a batch file
drgt wrote:Please check again
sorry, not verify again
- try on another comp;
- try this last edition:
Code: Select all
@echo off
SetLocal DisableDelayedExpansion
set d1=c:\test1
set d2=d:\test2
echo -----
echo :1 2:
echo -----
for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
set "$f=%%i"& SetLocal EnableDelayedExpansion
if /i not "!$i!"=="!$f!" (
if not exist "%d1%\!$f!" (echo :. +: !$f!) else (
if not exist "%d2%\!$f!" (echo :+ .: !$f!) else (
fc "%d1%\!$f!" "%d2%\!$f!" >nul&& echo := =: !$f!|| echo :^< ^>: !$f!)))
EndLocal& set "$i=%%i"
)
- try debug both attempts with full logging (with 1'st @echo on)
Code: Select all
fico.cmd >fico_1.log 2>&1
fico.cmd >fico_2.log 2>&1
with detailed compare this tow logs
Use of FOR in a batch file
Here are the requested logs.
You see the 2nd run is different. I am running xp media center sp2. Do I have a different command interpreter?
THE CODE YOU ARE SUGGESTING IN PREVIOUS POST ALSO YIELDED NOTHING PERHAPS BECAUSE I RUN IT AFTER THE CODE HEREIN.
I RUN "SET" AFTER THESE BATCHES:
C:\>SET
$i=New Text Document.txt
d1=C:\Test\Comp1
d2=C:\Test\Comp2
SHOULD NOT THESE BE CLEARED AT THE END OF THE BATCH FILE?
COULD THIS BE THE CAUSE OF THE PROBLEM?
fico_log1:
-----------
C:\>rem @echo off
C:\>set d1=C:\Test\Comp1
C:\>set d2=C:\Test\Comp2
C:\>echo -----
-----
C:\>echo :1 2:
:1 2:
C:\>echo -----
-----
C:\>for /F "delims=" %i in ('dir /b/a-d "C:\Test\Comp1\*" "C:\Test\Comp2\*"|sort') do (
call set "$i=%$i:%i=%"
if defined $i (if not exist "C:\Test\Comp1\%i" (echo :. +: %i ) else (if not exist "C:\Test\Comp2\%i" (echo :+ .: %i ) else (fc "C:\Test\Comp1\%i" "C:\Test\Comp2\%i" 1>nul && echo := =: %i || echo :< >: %i ) ) )
set "$i=%i"
)
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
:= =: New Text Document.txt
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
========================================
fico_log2:
------------
C:\>rem @echo off
C:\>set d1=C:\Test\Comp1
C:\>set d2=C:\Test\Comp2
C:\>echo -----
-----
C:\>echo :1 2:
:1 2:
C:\>echo -----
-----
C:\>for /F "delims=" %i in ('dir /b/a-d "C:\Test\Comp1\*" "C:\Test\Comp2\*"|sort') do (
call set "$i=%$i:%i=%"
if defined $i (if not exist "C:\Test\Comp1\%i" (echo :. +: %i ) else (if not exist "C:\Test\Comp2\%i" (echo :+ .: %i ) else (fc "C:\Test\Comp1\%i" "C:\Test\Comp2\%i" 1>nul && echo := =: %i || echo :< >: %i ) ) )
set "$i=%i"
)
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
MISSING!!!!!!!!!!
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
You see the 2nd run is different. I am running xp media center sp2. Do I have a different command interpreter?
THE CODE YOU ARE SUGGESTING IN PREVIOUS POST ALSO YIELDED NOTHING PERHAPS BECAUSE I RUN IT AFTER THE CODE HEREIN.
I RUN "SET" AFTER THESE BATCHES:
C:\>SET
$i=New Text Document.txt
d1=C:\Test\Comp1
d2=C:\Test\Comp2
SHOULD NOT THESE BE CLEARED AT THE END OF THE BATCH FILE?
COULD THIS BE THE CAUSE OF THE PROBLEM?
fico_log1:
-----------
C:\>rem @echo off
C:\>set d1=C:\Test\Comp1
C:\>set d2=C:\Test\Comp2
C:\>echo -----
-----
C:\>echo :1 2:
:1 2:
C:\>echo -----
-----
C:\>for /F "delims=" %i in ('dir /b/a-d "C:\Test\Comp1\*" "C:\Test\Comp2\*"|sort') do (
call set "$i=%$i:%i=%"
if defined $i (if not exist "C:\Test\Comp1\%i" (echo :. +: %i ) else (if not exist "C:\Test\Comp2\%i" (echo :+ .: %i ) else (fc "C:\Test\Comp1\%i" "C:\Test\Comp2\%i" 1>nul && echo := =: %i || echo :< >: %i ) ) )
set "$i=%i"
)
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
:= =: New Text Document.txt
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
========================================
fico_log2:
------------
C:\>rem @echo off
C:\>set d1=C:\Test\Comp1
C:\>set d2=C:\Test\Comp2
C:\>echo -----
-----
C:\>echo :1 2:
:1 2:
C:\>echo -----
-----
C:\>for /F "delims=" %i in ('dir /b/a-d "C:\Test\Comp1\*" "C:\Test\Comp2\*"|sort') do (
call set "$i=%$i:%i=%"
if defined $i (if not exist "C:\Test\Comp1\%i" (echo :. +: %i ) else (if not exist "C:\Test\Comp2\%i" (echo :+ .: %i ) else (fc "C:\Test\Comp1\%i" "C:\Test\Comp2\%i" 1>nul && echo := =: %i || echo :< >: %i ) ) )
set "$i=%i"
)
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
MISSING!!!!!!!!!!
C:\>(
call set "$i=%$i:New Text Document.txt=%"
if defined $i (if not exist "C:\Test\Comp1\New Text Document.txt" (echo :. +: New Text Document.txt ) else (if not exist "C:\Test\Comp2\New Text Document.txt" (echo :+ .: New Text Document.txt ) else (fc "C:\Test\Comp1\New Text Document.txt" "C:\Test\Comp2\New Text Document.txt" 1>nul && echo := =: New Text Document.txt || echo :< >: New Text Document.txt ) ) )
set "$i=New Text Document.txt"
)
Re: Use of FOR in a batch file
the code to reproduce error is:
this occur because $i var interfered between calls, you must clear it before
Code: Select all
call fico.cmd
call fico.cmd
this occur because $i var interfered between calls, you must clear it before
Code: Select all
set $i=& for /f "delims=" %%i in ('dir /b/a-d "%d1%\*" "%d2%\*"^|sort') do (
....
-
- Posts: 319
- Joined: 12 May 2006 01:13
Re: Use of FOR in a batch file
drgt wrote:Hi
I have 2 directories with the same files and I want to compare them using fc.exe. I do not quite understand how the "for...in...do" works.
I would also like to take advantage of fc's errorlevels if a file is not found for example.
I know how to redirect the dir command to create a list of the files I want to compare.
Thanks
You have posted since Sep and until now, you have not solved your problem.
Long ago since the time when there is Unix, the diff tool is used just for this purpose, comparing 2 directories( and files as wells). Now, on windows, you can use diff as well..download diff for windows here. then its simply
Code: Select all
diff c:\dir1 c:\dir2
No need to reinvent the wheel. you will be more productive using the correct tools for the job