web-dev-qa-db-ja.com

ディレクトリを再帰的に解析し、各ファイルを同じツリー構造のターゲットパスに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にすでに同じ名前のファイルが含まれている場合、テストは成功します。競合は無視され、リンクは作成されません。

標準のWindows10インストールで利用できるもの以外の追加の依存関係のないバッチファイルを使用してこれを行うにはどうすればよいですか?

2
Zhro

MKLinkを使用した再帰的なファイルおよびフォルダー構造のエミュレート

注:これは、既存のルートレベルのターゲットフォルダーで機能します。

for/d ループを使用して、ソースディレクトリ内の第1レベルのルートサブフォルダを繰り返し、次に/Dパラメータを指定して mklink コマンドを使用できます。 ディレクトリシンボリックリンクを作成して、ターゲットパスのルートディレクトリ内のサブフォルダをリンクし、必要に応じてそれぞれの下にエミュレートされたディレクトリ構造を作成し、それぞれの下のファイルも再帰的に参照されます。ルートレベルのターゲットフォルダは、このメソッドですでに存在できます。

次に、ソースディレクトリ内の第1レベルのファイルを反復する for ループを使用し、それに応じて mklink コマンドを使用して、ターゲットのルート内に直接シンボリックリンクとしてそれらを作成できます。ディレクトリ、およびルートレベルのターゲットフォルダは、このメソッドでもすでに存在できます。


バッチスクリプト

@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

結果

enter image description here

enter image description here

enter image description here


その他のリソース

  • FOR/D
  • [〜#〜] for [〜#〜]

  • バッチ置換(FOR /?)

    さらに、FOR変数参照の置換が強化されました。これで、次のオプションの構文を使用できます。

    %~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.
    
2
Pimp Juice IT

MKLinkを使用して、あるフォルダ構造から別のフォルダ構造へのシンボリックリンクを再帰的に作成しますが、ターゲットディレクトリにまだ存在しないファイルのみを対象とします

注:以下のソリューションでは、同じファイル名が既に存在する場合、ソースからターゲットのファイルへのシンボリックリンクの作成をスキップします。ターゲット。また、シンボリックリンクを作成する必要がある場合は、まだ存在していないターゲットパスサブフォルダーも作成されます。


1.バッチスクリプト(純粋なバッチ)

以下は、 for/r ループと setlocal enabledelayedexpansion および variable substrings を使用して、繰り返される完全なファイルパスとディレクトリ名を取得する純粋なバッチスクリプトソリューションです。ソースの場所から。これにより、これらの値から追加の変数が設定され、文字列からソースルートパスが解析され、ターゲットルートパスが文字列に連結されて、要件と上記の最上位の注記に従ってシンボリックリンクが作成されます。

重要:ここでSrcRoot=パス変数値の文字数を理解して、 変数)を設定できるようにすることが重要です。 substring その文字列内の同じ文字数をスキップして解析し、代わりにTargetRoot=変数値に置き換えることができる数値。

例:したがって、Z:\aは正確に4文字であり、Z:\ 、およびaはそれぞれ1文字としてカウントされます。合計すると、合計4つになります。したがって、これは、ループ内のロジックの~4および!oDir:~4!部分で!oFile:~4!が機能する場所です。したがって、SrcRoot値の各リテラル文字はそれぞれ1としてカウントされるので、それらを合計して、チルダ(~<#>)の後の数値をそれに置き換えます。

@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を使用)

以下は、 for/r ループにネストされた for/f ループを使用して、変数が渡された動的に作成および実行されたPowerShellスクリプトから変数名を取得するバッチスクリプトソリューションです。それに応じて、 replace メソッドを使用して処理し、ソースパスをターゲットパスに置き換えて、要件と上記の一番上のメモに従ってシンボリックリンクを作成します。

@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

その他のリソース

0
Pimp Juice IT

MKLinkを使用した再帰的なファイルおよびフォルダー構造のエミュレート

注:これは、ターゲットパスフォルダーがまだ存在しない場合にのみ機能します。

mklink コマンドを/Jパラメータとともに使用するだけで、リンクされたパスを指すディレクトリジャンクションを作成できます。 2つをリンクし、必要に応じてエミュレートされたディレクトリ構造を作成するソースのルートディレクトリの場所に移動し、下のファイルも再帰的に参照します。


バッチスクリプト

@ECHO ON

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

PAUSE
EXIT

結果

enter image description here

enter image description here

enter image description here


その他のリソース

  • 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.
    
0
Pimp Juice IT