如何递归解析目录并将每个文件 MKLINK 到具有相同树结构的目标路径中

如何递归解析目录并将每个文件 MKLINK 到具有相同树结构的目标路径中

我有一个目录a\,其中包含我想复制到路径中的文件和子目录,b\而不是复制文件,而是想对每个文件执行调用MKLINK <link> <target>到新路径,而不是执行实际的复制。

如果我有一个目录:

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

我从路径复制链接a\b\结果如下:

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

如果目标目录没有匹配的文件夹结构,则目录层次结构将保留为非链接文件夹。请注意只有文件是链接

成功的测试将在Z:\b空目录、Z:\b包含文件夹Z:\b\some_path和先前的测试但Z:\b可能已经包含同名文件的情况下成功;冲突将被忽略并且不会为它们创建链接。

如何使用批处理文件来执行此操作,并且除了标准 Windows 10 安装中提供的依赖项之外没有其他依赖项?

答案1

以递归方式创建从一个文件夹结构到另一个文件夹结构的符号链接MKLink,但仅限于目标目录中尚不存在的文件

笔记: 如果目标中已存在相同文件名,则以下解决方案将跳过从源创建指向目标文件的符号链接。如果需要创建符号链接,它还将创建尚不存在的目标路径子文件夹。


1.批处理脚本(纯批处理)

下面是使用一个纯批处理脚本解决方案对于/r循环设置本地启用延迟扩展变量子串从源位置获取迭代的完整文件路径和目录名称。这将根据从字符串解析源根路径的值来设置其他变量,然后将目标根路径连接回字符串,以便根据您的要求和上面的注释相应地创建符号链接。

重要的:了解路径变量值中的字符数非常重要SrcRoot=,这样您就可以设置 变量子串数字跳过该字符串中相同数量的字符来解析它,以便可以用TargetRoot=变量值替换它。

例如:因此,Z:\a正好是 4 个字符Z,其中:\、 和a每个都算作 1 个字符。总计起来是 4 个;因此,这就是循环内逻辑的和 部分~4发挥作用的地方。因此,值中的每个文字字符都将算作 1,因此将它们相加并用它替换波浪符号 ( ) 后的数字。!oDir:~4!!oFile:~4!SrcRoot~<#>

@ECHO ON

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

SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R "%SrcRoot%" %%A IN ("*") DO (
  SET oDir=%%~DPA
  SET oFile=%%~A
  IF NOT EXIST "%TargetRoot%!oDir:~4!" MD "%TargetRoot%!oDir:~4!"
    IF NOT EXIST "%TargetRoot%!oFile:~4!" MKLINK "%TargetRoot%!oFile:~4!" "%%~A"
  )

PAUSE
EXIT

2.批处理脚本(使用PowerShell)

下面是使用批处理脚本解决方案对于/r循环嵌套在对于/f循环从动态创建并执行的 PowerShell 脚本中获取变量名称,并相应地传递变量,然后进行处理 代替方法用目标路径替换源路径,然后根据您的要求和上面最上面的注释创建符号链接。

@ECHO ON

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

CALL :PowerShell

FOR /R "%SrcRoot%" %%A IN ("*") DO (
  CD /D "%PowerShellDir%"
  FOR /F "TOKENS=*" %%B IN ('Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '"%SrcRoot%"' '"%TargetRoot%"' '"%%~A"'"') DO (
      IF NOT EXIST "%%~DPB" MD "%%~DPB"
      IF NOT EXIST "%%~B" MKLINK "%%~B" "%%~A"
      )
  )

PAUSE
EXIT

:PowerShell
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
SET PSScript=%temp%\~tmpStrFldrRplc.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Source = $args[0]>"%PSScript%"
ECHO $Dest   = $args[1]>>"%PSScript%"
ECHO $FPath  = $args[2]>>"%PSScript%"
ECHO $var    = $FPath.Replace($Source,$Dest)>>"%PSScript%"
ECHO Write-Output $Var>>"%PSScript%"
GOTO :EOF

更多资源

  • 支持/R
  • 设置本地启用延迟扩展
  • 变量:提取变量的一部分(子字符串)
  • 为/F
  • 代替
  • 脚本参数/参数

  • 批量替换 (FOR /?)

    此外,FOR 变量引用的替换功能也得到了增强。现在您可以使用以下可选语法:

    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    
  • 明基林克

  • 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.
    

答案2

使用以下代码模拟递归文件和文件夹结构MKLink

笔记: 这适用于已经存在的根级目标文件夹。

您可以使用对于/d循环迭代源目录中的第一级根子文件夹,然后使用链接/D参数的命令来创建目录符号链接链接目标路径根目录中的那些子文件夹,根据需要在每个子文件夹下创建一个模拟目录结构,并且每个子文件夹下的文件也被递归引用 - 使用此方法,根级目标文件夹可以已经存在。

然后您可以使用为了循环迭代源目录中的第一级文件,然后使用链接命令相应地在目标目录的根目录中创建它们作为直接符号链接,并且根级目标文件夹也可以通过此方法存在。


批处理脚本

@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

结果

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述


更多资源

  • 致/D
  • 为了

  • 批量替换 (FOR /?)

    此外,FOR 变量引用的替换功能也得到了增强。现在您可以使用以下可选语法:

    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    
  • 明基林克

  • 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.
    

答案3

使用以下代码模拟递归文件和文件夹结构MKLink

笔记: 仅当目标路径文件夹不存在时,此方法才会起作用。

您只需使用链接/J参数的命令来创建目录连接点将链接路径指向源根目录的位置,将两者链接起来,并根据需要创建一个模拟目录结构,其中下面的文件也被递归引用。


批处理脚本

@ECHO ON

SET SrcRoot=Z:\a
SET LinkRoot=Z:\b
MKLINK /J "%LinkRoot%" "%SrcRoot%"

PAUSE
EXIT

结果

在此处输入图片描述

在此处输入图片描述

在此处输入图片描述


更多资源

  • 明基林克
  • 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.
    

相关内容