web-dev-qa-db-ja.com

ディレクトリ構造をコピーするが、特定のファイルのみを含める方法(Windowsバッチファイルを使用)

タイトルにあるように、ディレクトリ構造を再帰的にコピーし、一部のファイルのみを含めるにはどうすればよいですか。たとえば、次のディレクトリ構造がある場合:

folder1
  folder2
    folder3
      data.Zip
      info.txt
      abc.xyz
    folder4
    folder5
      data.Zip
      somefile.exe
      someotherfile.dll

ファイルdata.Zipおよびinfo.txtは、ディレクトリ構造のあらゆる場所に表示できます。ディレクトリ構造全体をコピーする方法はありますが、data.Zipおよびinfo.txtという名前のファイルのみを含めることができます(他のすべてのファイルは無視する必要があります)。

結果のディレクトリ構造は次のようになります。

copy_of_folder1
  folder2
    folder3
      data.Zip
      info.txt
    folder4
    folder5
      data.Zip
91
M4N

バッチのみにする必要があるかどうかは言及しませんが、ROBOCOPYを使用できる場合は、これを試してください。

ROBOCOPY C:\Source C:\Destination data.Zip info.txt /E

編集:/Sパラメーターを/Eに変更して、空のフォルダーを含めるようにしました。

148
aphoria

一度に1つのファイルをコピーし、ROBOCOPYを必要としない代替ソリューション:

@echo off
setlocal enabledelayedexpansion

set "SOURCE_DIR=C:\Source"
set "DEST_DIR=C:\Destination"
set FILENAMES_TO_COPY=data.Zip info.txt

for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
    if exist "%%F" (
        set FILE_DIR=%%~dpF
        set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
        xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
    )
)

外側のforステートメントは、SOURCE_DIRのサブディレクトリとFILENAMES_TO_COPYの名前の可能なパスの組み合わせを生成します。既存のファイルごとにxcopyが呼び出されます。 FILE_INTERMEDIATE_DIRは、SOURCE_DIR内に作成する必要があるDEST_DIR内のファイルのサブディレクトリパスを保持します。

29
sakra

findの出力(ファイルパスなど)をcpioにパイプしてみてください

find . -type f -name '*.jpg' | cpio -p -d -v targetdir/

cpioはターゲットファイルのタイムスタンプをチェックするため、安全で高速です。

慣れたら、-vを削除して操作を高速化します。

13
Gabe Rainbow

Powershellがオプションの場合、これを行うことができます。

Copy-Item c:\sourcePath d:\destinationPath -filter data.Zip -recurse

主な欠点は、指定したフィルターに一致するファイルがないために最終的に空になる場合でも、すべてのフォルダーをコピーすることです。そのため、必要なファイルがあるいくつかのフォルダーに加えて、空のフォルダーでいっぱいのツリーになる可能性があります。

8
Neil

以前の回答に感謝します。 :)

「r4k4copy.cmd」という名前のこのスクリプト:

@echo off
for %%p in (SOURCE_DIR DEST_DIR FILENAMES_TO_COPY) do set %%p=
cls
echo :: Copy Files Including Folder Tree
echo :: http://stackoverflow.com
rem     /questions/472692/how-to-copy
rem     -a-directory-structure-but-only
rem     -include-certain-files-using-windows
echo :: ReScripted by r4k4
echo.
if "%1"=="" goto :NoParam
if "%2"=="" goto :NoParam
if "%3"=="" goto :NoParam
setlocal enabledelayedexpansion
set SOURCE_DIR=%1
set DEST_DIR=%2
set FILENAMES_TO_COPY=%3
for /R "%SOURCE_DIR%" %%F IN (%FILENAMES_TO_COPY%) do (
if exist "%%F" (
set FILE_DIR=%%~dpF
set FILE_INTERMEDIATE_DIR=!FILE_DIR:%SOURCE_DIR%=!
xcopy /E /I /Y "%%F" "%DEST_DIR%!FILE_INTERMEDIATE_DIR!"
)
)
goto :eof
:NoParam
echo.
echo Syntax: %0 [Source_DIR] [Dest_DIR] [FileName]
echo Eg.   : %0 D:\Root E:\Root\Lev1\Lev2\Lev3 *.JPG
echo Means : Copy *.JPG from D:\Root to E:\Root\Lev1\Lev2\Lev3

「Source」、「Destination」、および「FileName」の変数を受け入れます。また、指定されたタイプのファイルまたは選択的なファイル名のみをコピーできます。

改善を歓迎します。 :)

7
Rhak Kahr

Findおよびcpのみ:

mkdir /tmp/targetdir
cd sourcedir
find . -type f -name '*.Zip' -exec cp -p --parents {} /tmp/targetdir ";"
find . -type f -name '*.txt' -exec cp -p --parents {} /tmp/targetdir ";"
5
Rop

パウリウスのソリューションに似ていますが、気にしないファイルはコピーされずに削除されます:

@echo OFF

:: Replace c:\temp with the directory where folder1 resides.
cd c:\temp

:: You can make this more generic by passing in args for the source and destination folders.
for /f "usebackq" %%I in (`dir /b /s /a:-d folder1`) do @echo %%~nxI | find /V "data.Zip" | find /v "info.txt" >> exclude_list.txt
xcopy folder1 copy_of_folder1 /EXCLUDE:exclude_list.txt /E /I
4
Patrick Cuff

これは2つの簡単なコマンドですが、コピーする必要のないファイルが小さい場合を除き、これはお勧めしません。これは、これによりすべてのファイルがコピーされ、コピーに不要なファイルが削除されるためです。

xcopy /E /I folder1 copy_of_folder1
for /F "tokens=1 delims=" %i in ('dir /B /S /A:-D copy_of_files ^| find /V "info.txt" ^| find /V "data.Zip"') do del /Q "%i"

確かに、2番目のコマンドは少し長いですが、動作します!

また、このアプローチでは、サードパーティのツールをダウンロードしてインストールする必要はありません(Windows 2000+ BATCHにはこれに十分なコマンドがあります)。

3
Paulius

Linuxおよびその他のUNIXシステムでは、tarコマンドを使用すると簡単に実行できます。

$ tar cvf /tmp/full-structure.tar *data.Zip *info.txt

次に、ターゲットにcwdして、次の操作を行います。

$ tar xvf /tmp/full-structure.tar 

もちろん、最初のtarからの出力を2番目のtarにパイプすることもできますが、それが段階的に動作するのを見る方が理解と説明が簡単です。次のコマンドに必要なcd/to/new/path /がありません-今、その方法を思い出せません。できれば他の誰かが追加できます。

$ tar cvf -  *data.Zip *info.txt |  tar xvf - 

Tar(gnutar)はWindowsでも使用できますが、おそらくそのプラットフォームではxcopyメソッドを使用するでしょう。

2
JohnP

WinRARコマンドラインインターフェイスを使用すると、ファイル名やファイルタイプをアーカイブにコピーできます。次に、そのアーカイブを任意の場所に抽出できます。これにより、元のファイル構造が保持されます。

音楽自体を再コピーすることなく、不足しているアルバム画像ファイルを携帯電話に追加する必要がありました。幸いなことに、ディレクトリ構造は私のコンピューターとモバイルで同じでした!

私が使用した:

   rar a -r C:\Downloads\music.rar X:\music\Folder.jpg
  • C:\ Downloads\music.rar =作成されるアーカイブ
  • X:\ music\=音楽ファイルを含むフォルダー
  • Folder.jpg =コピーしたいファイル名

これにより、適切なサブディレクトリにすべてのFolder.jpgファイルを含むアーカイブが作成されました。

この手法は、ファイルタイプのコピーにも使用できます。ファイルの名前がす​​べて異なる場合は、すべてのファイルを単一のディレクトリに抽出することを選択できます。追加のコマンドラインパラメーターは、複数のファイルタイプをアーカイブできます。

この非常に役立つリンクの詳細 http://cects.com/using-the-winrar-command-line-tools-in-windows/

1
Jim_Joat

Altap Salamander (2 panel file manager)を使用する場合:[コピー]ポップアップのオプションで、ファイル名またはマスクを指定します。簡単です。

1
Hugo P
XCOPY /S folder1\data.Zip copy_of_folder1  
XCOPY /S folder1\info.txt copy_of_folder1

編集:空のフォルダーを保持する場合(投稿を再読み込みすると、/ Sではなく/ Eを使用するようです)。

1
gkrogers

私は正規表現、怠zyでインストールが嫌いなので、ディレクトリを作成してVanilla DOSコマンドでコピーするバッチファイルを作成しました。面倒ですが、robocopyを実行するよりも速いです。

  1. テキストファイルに、necの場合はドライブ文字を含む完全なパスを持つソースファイルのリストを作成します。
  2. テキストエディターで正規表現を有効にします。
  3. スペースの場合、各行に二重引用符を追加します-検索文字列(.*)文字列"\1"を置換し、すべて置換をクリックします
  4. ファイルごとに2行を作成します-1つはディレクトリを作成し、1つはファイルをコピーします(qqqは宛先パスに置き換えられます)-検索文字列(.*)文字列md qqq\1\nxcopy \1 qqq\1\nを検索し、すべて置換をクリックします
  5. 宛先パスからファイル名を削除します-\\([^\\^"]+)"\nを検索\\"\nを置換
  6. 宛先パスで置き換えます(この例では、A:\srcおよびB:\dest)。正規表現をオフにし、qqq"A:\src\を置換B:\dest\を検索して、[すべて置換]をクリックします。

mdはネストされたディレクトリを作成します。この例では、おそらくcopyはxcopyと同じように動作します。上書き確認を抑制するには、xcopyに/ Yを追加することをお勧めします。次のようなバッチファイルになります。

md "B:\dest\a\b\c\"
xcopy "C:\src\a\b\c\e.xyz" "B:\dest\a\b\c\e.xyz"

元のリストのすべてのファイルに対して繰り返されます。 Win7でテスト済み。

0
Chris