How to parse a directory recursively and MKLINK each file into a target path with the same tree structure

batch filecmd.execommand linesymbolic-linkwindows

I have a directory a\ containing files and sub-directories that I want to copy into path b\ where instead of copying the files I want to perform a call to MKLINK <link> <target> on each file into the new path rather than performing an actual copy.

So if I have a directory:

Z:\a\file1.txt
Z:\a\file2.txt
Z:\a\some_path\file3.txt
Z:\a\some_path\file4.txt

And I copy links from path a\ to b\ the result will look like:

Z:\b\file1.txt           <<===>> z:\a\file1.txt
Z:\b\file2.txt           <<===>> z:\a\file2.txt
Z:\b\some_path\file3.txt <<===>> z:\a\some_path\file3.txt
Z:\b\some_path\file4.txt <<===>> z:\a\some_path\file4.txt

The directory hierarchy is to be preserved as non-link folders in the event that the target directory does not have a matching folder structure. Note that only the files are links.

A successful test will succeed where Z:\b is an empty directory, Z:\b contains a folder Z:\b\some_path, and either previous tests but Z:\b my already contain files of the same name; conflicts are ignored and no link is created for them.

How can I do this using a batch file with no additional dependencies beyond what is available in a standard Windows 10 installation?

Best Answer

Emulating a Recursive File and Folder Structure with MKLink

Note: This works with an already existing root level target folder.

You can use a for /d loop and iterate the first level root sub-folders within the source directory, and then use the mklink command with the /D parameter to create directory symbolic links to link those sub-folders in the target path's root directory creating an emulated directory structure beneath each as you desire with files beneath each being referenced recursively too—the root level target folder can already exist with this method.

You can then use a for loop iterating the first level files within the source directory and then use the mklink command accordingly to create those as direct symbolic links within the root of the target directory, and the root level target folder can already exist with this method too.


Batch Script

@ECHO ON

SET SrcRoot=Z:\a
SET TargetRoot=Z:\b

FOR /D %%A IN ("%SrcRoot%\*") DO (
    MKLINK /D "%TargetRoot%\%%~NA" "%%~A"
    )

FOR %%A IN ("%SrcRoot%\*") DO (
    MKLINK "%TargetRoot%\%%~NXA" "%%~A"
    )

PAUSE
EXIT

Results

enter image description here

enter image description here

enter image description here


Further Resources

  • FOR /D
  • FOR

  • Batch Substitutions (FOR /?)

    In addition, substitution of FOR variable references has been enhanced. You can now use the following optional syntax:

    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    
  • MKLink

  • mklink /?

    Creates a symbolic link.
    
    MKLINK [[/D] | [/H] | [/J]] Link Target
    
            /D      Creates a directory symbolic link.  Default is a file
                    symbolic link.
            /H      Creates a hard link instead of a symbolic link.
            /J      Creates a Directory Junction.
            Link    Specifies the new symbolic link name.
            Target  Specifies the path (relative or absolute) that the new link
                    refers to.
    
Related Question