ファイルを含む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以降を想定)
/ 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"
)
_
代わりにROBOCOPYが好きです。 XCOPYを何年もの間使用していたところ、低速/単調なインターネット接続を介した再起動可能なコピー操作が必要であることがわかりました。
ROBOCOPY src dest/s/e/xo
または鏡
ROBOCOPY src dest/mir
ロギングオプションを使用して、後で検査するためにリストを取得します。
ROBOCOPY src dest/s/e/xo/log:file