Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

two trees

Jun
127
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.
 
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
 
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.
 
What I'd like to do is have a routine to compare two folder trees and delete the exact matches in one.....
 
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?
 
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.
 
You should probably check for existence before you do the CRC compare.
Code:
if not exists %rhs iterate
iff %@crc32[%f] ...
 
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 ?
 
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).
 
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....
 

Attachments

  • CmprFldrs.btm
    1.1 KB · Views: 236
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
 
Yes I am familiar with COMMENT / ENDCOMMENT, rem, and labels used as comment markings...
 
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
 
Back
Top