web-dev-qa-db-ja.com

あるフォルダーから別のフォルダーに新しいファイルのみをコピーする

ファイルを含む2つのフォルダーがあります。これらのファイルは、いくつかのビルドプロセスの産物です。最初のフォルダーは前のビルドの出力で、後者は現在のビルドの出力です。

コマンドライン/ビルドスクリプトからこれらの2つのフォルダーを何らかの方法で比較し、追加されたファイルのみまたは他のフォルダーに新しいファイルをコピーしたいと思います。

例えば:

**FOLDER1** (new build)
a.txt
b.txt (modified)
c.txt
d.txt

**FOLDER2** (prev build)
a.txt
b.txt
c.txt

これに基づいて、私が興味のあるコピー操作は、b.txtとd.txtのみを他のフォルダーにコピーします(folder2にはコピーしません)。

基本的に、私は「デルタ」の後だけにあり、これらをいくつかの場所に保存したいと思います。

これは、Windowsに付属する標準のコマンドラインツールを使用して可能ですか? (Windows 7/Server 2008以降を想定)

8
liortal

/ Dおよび/ Lオプションを指定してXCOPYを使用し、フォルダー1からフォルダー2に「コピー」します。

/ Dオプションは、コピーを新しいファイルまたは変更されたファイルのみに制限します。

/ Lオプションを指定すると、コピーされるファイルが一覧表示されますが、実際にコピーが行われることはありません。

次に、FOR/Fを使用してこれらの結果を処理し、実際にファイルをフォルダー3にコピーします。

_for /f "eol=: delims=" %F in ('xcopy /dl "folder1\*" "folder2"') do @copy "%F" "f3" >nul
_

バッチファイルに入れる場合、すべての_%_を_%%_として2倍にする必要があります。

XCOPYは、影響を受ける(影響を受ける)ファイルの数の概要も出力します。上記は、サマリカウント「名前」のファイルをコピーしようとしますが、もちろん失敗します。出力をnulにリダイレクトすると、エラーメッセージが表示されなくなります。私はWindows 7でテストしましたが、エラーメッセージがstderrではなくstdoutにあることに驚きました。他のバージョンのエラーメッセージがstderrに表示されている場合、コマンドはエラーメッセージを防ぐために2> nulも取得する必要があります。

しかし、エラーメッセージを非表示にすることにはリスクがあります-何らかの理由でコピーが失敗した場合はどうなりますか?

次のスクリプトは、正常にコピーされたすべてのファイルを一覧表示し、失敗したファイル(ある場合)を示します。 FINDSTRを使用して、不要なファイル数を除外します。ファイル数はNNN File(s)の形式の英語であると想定しているため、他の言語用に変更する必要があります。

_@echo off
for /f "eol=: delims=" %%F in (
  'xcopy /dl "folder1\*" "folder2" ^| findstr /v "^[0-9][0-9]* File(s)"'
) do copy "%%F" "folder3" >nul && echo "%%F"|| echo FAILED: "%%f"
_

以下は、任意の言語で機能するより複雑なバリアントです。各ファイル名を変数に保存し、次のループ反復までコピーを遅らせます。最後のエントリ(カウント)は決してコピーされません。

_@echo off
setlocal disableDelayedExpansion
set "file="
for /f "eol=: delims=" %%F in ('xcopy /dl "folder1\*" "folder2"') do (
  if defined file (
    setlocal enableDelayedExpansion
    copy "!file!" "folder3" >nul && echo "!file!" || echo FAILED: "!file!"
    endlocal
  )
  set "file=%%F"
)
_
11
dbenham

代わりにROBOCOPYが好きです。 XCOPYを何年もの間使用していたところ、低速/単調なインターネット接続を介した再起動可能なコピー操作が必要であることがわかりました。

ROBOCOPY src dest/s/e/xo

または鏡

ROBOCOPY src dest/mir

ロギングオプションを使用して、後で検査するためにリストを取得します。

ROBOCOPY src dest/s/e/xo/log:file

2
Joe