1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

for %1 %%i in (*.*) do [...] not working

Discussion in 'Support' started by roytam1, Apr 15, 2010.

  1. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    This one should work:
    Code:
    @echo off
    setlocal enabledelayedexpansion
    for /R %%i in (.) do (
     call :rpath "%%~i"
     echo !rpath!
    )
    endlocal
    GOTO :EOF
    
    rem sub rpath(filename) OUT: %rpath%
    :rpath
     rem debug print %1 here
     echo (rpath: %1)
    
     SET rpath=%~1
     set rpath=!rpath:%CD%\=!
    GOTO :EOF
     
    #31
  2. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    and this one match original usage of variables:
    Code:
    @echo off
    setlocal enabledelayedexpansion
    for /R %%i in (.) do call :disprpath "%%~i"
    endlocal
    GOTO :EOF
    
    rem sub disprpath(filename)
    :disprpath
     call :rpath "%~1"
     echo %rpath%
    GOTO :EOF
    
    rem sub rpath(filename) OUT: %rpath%
    :rpath
     rem debug print %1 here
     rem echo (rpath: %1)
    
     SET rpath=%~1
     set rpath=!rpath:%CD%\=!
    GOTO :EOF
    And I noticed that TCC changes %CD% when doing recursive FOR loop.
     
    #32
  3. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    SET rpath=%~1 removes any surrounding quotes (") from %1.
     
    #33
  4. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    904
    Likes Received:
    4
    Re: not working

    I did get your code to run in CMD. However, it is much easier to do this
    in TCC:

    function rpath=.\%%@right[-%@len[%_CWDS],%%@full[%%1]]
    do fi in /S /a:d *
    echo full: %@full[%fi] rpath: %@rpath[%fi]
    enddo

    One difference is that the current directory ".\" is not included in the
    loop. Only the subdirectories of .\ are included. However, if the intent
    is to operate on the files and not just the directories, then removing the
    /a:d switch yields exactly what I expect.

    Another thing to keep in mind is that as DO recurses into each
    subdirectory the CWD changes. So the need for a relative path is
    diminished.

    -Scott

    roytam1 <> wrote on 04/21/2010 12:27:26 AM:


    my

    AFAIK

    does

    get is

     
    #34
  5. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    7,400
    Likes Received:
    27
    Re: not working

    There's two problems with this batch file. The first is the same as the
    previous batch file -- there's a character inside the substitution variable
    ('\') that TCC doesn't like. Though unlike the case of %abc: ...%, I can
    add a kludge to TCC to accept it and only look for a closing ! if
    DelayedExpansion is set.

    The second problem is below ...


    TCC is right, and CMD is wrong. CMD's behavior is a bug -- the problem
    being that CMD is expanding %CD% before executing the FOR, despite (1)
    delayed expansion being set, and (2) the %CD% variable being embedded in a
    delayed expansion variable. As I said before, I am definitely *not*
    changing TCC to expand all variables before execution.

    Rex Conn
    JP Software
     
    #35
  6. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    For the second problem, even if I use !CD! instead of %CD%, CMD won't change %CD% variable to "current directory where recursive FOR loop goes". Because CMD does not "Change Directory" in recursive FOR loop, but lookup files in subdirectories in "Current Directory" where "FOR /R" runs.

    a CMD script that emulating equivalent behavior in TCC will look like this:
    Code:
    @echo off
    setlocal enabledelayedexpansion
    for /R %%i in (.) do call :disprpath "%%~i"
    endlocal
    GOTO :EOF
    
    rem sub disprpath(filename)
    :disprpath
     cd "%~1"
     call :rpath "%~1"
     echo %rpath%
    GOTO :EOF
    
    rem sub rpath(filename) OUT: %rpath%
    :rpath
     rem debug print %1 here
     rem echo (rpath: %1)
     echo (CD: %CD%)
    
     SET rpath=%~1
     set rpath=!rpath:%CD%\=!
    GOTO :EOF
    but this one can be workaround for TCC by setting another variable to %CD% before recursive FOR loop and use it instead of %CD%.
     
    #36
  7. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    7,400
    Likes Received:
    27
    Re: not working

    No, that's not what CMD does. From the CMD help:

    ---------
    FOR /R
    Walks the directory tree rooted at [drive:]path, executing the FOR
    statement in each directory of the tree.
    ---------

    There is no way to execute the FOR statement without changing the current
    directory. (And monitoring CMD shows it doing exactly that.)

    Rex Conn
    JP Software
     
    #37
  8. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    #38
  9. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    7,400
    Likes Received:
    27
    Re: not working

    This has nothing to do with escape characters or delayed variables. (The escape characters are being stripped in the SET command in both CMD and TCC.)

    What's happening is that in CMD it is doing the redirection before the delayed expansion; in TCC the redirection occurs after variable expansion. This is a TCC feature (allowing you to define redirection in your variables), and will definitely not be changed.
     
    #39
  10. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    quote from http://ss64.com/nt/setlocal.html :
    With delayed expansion the caret ^ escapes each special character all the time, not just for one command.
    This makes it possible to work with HTML and XML formatted strings in a variable.
     
    #40
  11. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    but with this script, it proves CMD not only have %CD% unchanged, but really not changing "current directory" by CD/CHDIR:
    Code:
    @echo off
    setlocal enabledelayedexpansion
    for /R %%i in (.) do call :disprpath "%%~i"
    endlocal
    GOTO :EOF
    
    rem sub disprpath(filename)
    :disprpath
     cd
     call :rpath "%~1"
     echo rpath = %rpath%
    GOTO :EOF
    
    rem sub rpath(filename) OUT: %rpath%
    :rpath
     rem debug print %1 here
     echo (rpath: %1)
     echo (CD in rpath: %CD%)
    
     SET rpath=%~1
     set rpath=!rpath:%CD%\=!
    GOTO :EOF
    CMD:
    H:\test>forx.bat
    H:\test
    (rpath: "H:\test\.")
    (CD in rpath: H:\test)
    rpath = .
    H:\test
    (rpath: "H:\test\dir1\.")
    (CD in rpath: H:\test)
    rpath = dir1\.
    H:\test
    (rpath: "H:\test\dir1\dir1-1\.")
    (CD in rpath: H:\test)
    rpath = dir1\dir1-1\.
    H:\test
    (rpath: "H:\test\dir2\.")
    (CD in rpath: H:\test)
    rpath = dir2\.

    TCC:
    [H:\test]forx.bat
    H:\test
    (rpath: "H:\test\.")
    (CD in rpath: H:\test)
    rpath = .
    H:\test\dir1
    (rpath: "H:\test\dir1\.")
    (CD in rpath: H:\test\dir1)
    rpath = .
    H:\test\dir1\dir1-1
    (rpath: "H:\test\dir1\dir1-1\.")
    (CD in rpath: H:\test\dir1\dir1-1)
    rpath = .
    H:\test\dir2
    (rpath: "H:\test\dir2\.")
    (CD in rpath: H:\test\dir2)
    rpath = .
     
    #41
  12. roytam1

    Joined:
    Apr 1, 2010
    Messages:
    43
    Likes Received:
    0
    Re: not working

    I'll agree with you for TCC style variables. *BUT* not with CMD's !var! style delayed variables.
     
    #42
  13. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    7,400
    Likes Received:
    27
    Re: not working

    The delayed expansion isn't relevant.

    I have no intention of duplicating this tortured syntax, because:

    1) It's undocumented by Microsoft (and IMO is more likely to be a bug than a
    feature)

    2) It's exceptionally goofy

    3) It's completely useless, as there's a simpler, documented, and actually
    used syntax that works in both CMD and TCC:

    Set _html=^^^<title^^^>Hello world ^^^</title^^^>
    Echo %_html%

    TCC also has an even simpler solution:

    Echo `<title>Hello world </title>`

    Rex Conn
    JP Software
     
    #43
  14. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    7,400
    Likes Received:
    27
    Re: not working

    Already possibly (more easily); see my other post.

    Rex Conn
    JP Software
     
    #44

Share This Page