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

two trees

Discussion in 'T&T - Miscellaneous' started by Roedy, Nov 9, 2011.

  1. Roedy

    Joined:
    Jun 8, 2008
    Messages:
    96
    Likes Received:
    2
    I often want to do operations on two directory trees of files.

    I might check for a file to see if it exists in one tree but not the other. doing something to transform a file in one tree to a corresponding slot in the other with a different extension, find out which tree has the newer of each file etc.

    GLOBAL seems to be only applicable to a single tree.

    FOR /r %i is just the file name. It does not give you the depth you are so you can find the corresponding spot in some other tree.

    What other tools are there? If none, maybe you could invent something like GLOBAL that used two trees.
     
  2. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    From: Roedy
    |...
    | FOR /r %i is just the file name. It does not give you the depth you
    | are so you can find the corresponding spot in some other tree.

    In fact, %i is the full path in that FOR. What you can do is

    %@replace[root1,root2,%i] to get the corresponding filespec in the alternate tree. I do that often!
    --
    HTH, Steve
     
  3. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    I have found that the behavior of FOR and DO differ in regard to paths.
    But my experience with FOR is exactly the opposite of what you are
    describing.

    This command yields full paths and file names:
    Code:
    for /r %f in (*) do echo "%f"
    
    Whereas this command yields just file names:
    Code:
    do f in /a:-d /s * (echo "%f")
    
    But you can "fix" that by:
    Code:
    do f in /a:-d /s * (echo "%_cwds%%f")
    
    -Scott



    I often want to do operations on two directory trees of files.

    I might check for a file to see if it exists in one tree but not the
    other. doing something to transform a file in one tree to a corresponding
    slot in the other with a different extension, find out which tree has the
    newer of each file etc.

    GLOBAL seems to be only applicable to a single tree.

    FOR /r %i is just the file name. It does not give you the depth you are so
    you can find the corresponding spot in some other tree.

    What other tools are there? If none, maybe you could invent something like
    GLOBAL that used two trees.
     
  4. Charles G

    Joined:
    Apr 2, 2011
    Messages:
    664
    Likes Received:
    0
    What I'd like to do is have a routine to compare two folder trees and delete the exact matches in one.....
     
  5. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    Can you give an example?
     
  6. Charles G

    Joined:
    Apr 2, 2011
    Messages:
    664
    Likes Received:
    0
    compare <root1>... with <root2>.... and if root1\dir1\dir2\file1.ext is the same CRC32 as root2\dir1\dir2\file1.ext then delete root2\dir1\dir2\file1.ext

    c:\CompareFolderTrees c:\dir1\ h:\dirz\

    ok?
     
  7. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    This simple approach should work.
    CompareFolderTrees.btm:
    Code:
    do f in /p dir /b1 /s /a:-d %1 
      rem %f will contain a relative path that includes %1
      rem this strips off %1 and replaces it with %2
      set rhs=%2%@right[-%@len[%1],%f]
      echos %f == %rhs ?
      iff %@crc32[%f] == %@crc32[%rhs] then
        echo (deleted)
        rem del /qe %rhs
      else
        echo.
      endiff
    enddo
    
    Caveat: I did not test it. So it will require some tweaking on your end.
     
  8. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    You should probably check for existence before you do the CRC compare.
    Code:
    if not exists %rhs iterate
    iff %@crc32[%f] ...
    
     
  9. Charles G

    Joined:
    Apr 2, 2011
    Messages:
    664
    Likes Received:
    0
    Thank you for the snippet. I am not sure about the /B1 .vs. /B on the DIR /s line. I read the CHM and see the /B1 specifies the relative name - but not sure why the /B1 is used and not /B ?
     
  10. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    Using B1 allows you to specify a subdirectory and not just a root directory. Say for example I am in C:\Foo and I want to run a comparison of subdirectory Bar against another subdirectory (e.g. C:\Foo\Bar and d:\Backups\Bar).

    If I invoke the DIR command as DIR /B /S Bar, the resulting output will contain full paths, e.g. C:\Foo\Bar\blahblahblah.

    If I use /B1 instead, the output contains a relative path, e.g. Bar\blahblahblah.

    Since the source directory might be in a different location than the current working directory, I have no reference to determine the relative path name. You want to replace the source directory path and keep the file name with the destination path. But you don't want to blindly remove the path (e.g. using @FILENAME and @EXT) because you might be in a subdirectory from where you started from, e.g. C:\Foo\Bar\Baz.

    @RIGHT is useful for removing a fixed length set of characters from the left of a string when the number to remove is negative. In the examples I'm using, you would want to remove C:\Foo\Bar from a full pathname or just Bar from a relative pathname.

    If you invoked your command as: CompareFolderTrees Bar\ D:\Backups\Bar\
    and you used /B, your source list would contain C:\Foo\Bar\blahblahblah. Given you started with just Bar\, how would you know you needed to strip off C:\Foo\Bar\ ?

    Granted you can play some games and figure it out. The @CWDS function can retrieve the CWD of a given drive. For the above example, %@CWDS[%1] (or %@CWDS[Bar\]) would return C:\Foo\. So you could strip off the leading C:\Foo\ but you'd still be left with a relative path of Bar\blahblahblah and if you specified D:\Backups\Bar as the comparison tree, you couldn't just prepend that because you'd get D:\Backups\Bar\Bar\blahblahblah (unless that's what you wanted).
     
  11. Charles G

    Joined:
    Apr 2, 2011
    Messages:
    664
    Likes Received:
    0
    Here is the latest BTM....

    1) Have to do a :Usage label

    2) Make sure the correct number of parameters are passed and both parms folders exist

    3) Allow saving the processing output to a user-specified file....
     

    Attached Files:

  12. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    You start your script with this:
    Code:
    goto :starthere
    
        CmprFldrTree <fldr1> <fldr2>
    
        Will compare folder trees and prompt to delete one folder
    
        https://jpsoft.com/forums/threads/two-trees.3351/#post-37763
    
    :starthere
    
    You can use either the COMMENT/ENDCOMMENT commands to enclose that text, REM statements, or :: labels. There really isn't a need for a goto.
    Code:
    COMMENT
        CmprFldrTree <fldr1> <fldr2>
    
        Will compare folder trees and prompt to delete one folder
    
        https://jpsoft.com/forums/threads/two-trees.3351/#post-37763
    ENDCOMMENT
    
    rem    CmprFldrTree <fldr1> <fldr2>
    rem
    rem    Will compare folder trees and prompt to delete one folder
    rem
    rem    https://jpsoft.com/forums/threads/two-trees.3351/#post-37763
    
    ::    CmprFldrTree <fldr1> <fldr2>
    ::
    ::    Will compare folder trees and prompt to delete one folder
    ::
    ::    https://jpsoft.com/forums/threads/two-trees.3351/#post-37763
    
     
  13. Charles G

    Joined:
    Apr 2, 2011
    Messages:
    664
    Likes Received:
    0
    Yes I am familiar with COMMENT / ENDCOMMENT, rem, and labels used as comment markings...
     
  14. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    977
    Likes Received:
    5
    BTW, saving the output to a file can easily be done using redirection.
    Code:
    CmprFldrTree Bar\ D:\Backups\Bar\ > bar.txt
    CmprFldrTree Bar\ D:\Backups\Bar\ | tee bar.txt
    
     

Share This Page