◆ E オプションで再帰+空フォルダも
◆ F でコピーの詳細表示 Q でコピー内容非表示
◆ H で隠しファイル系もコピー
◆ フォルダコピーにはとりあえず I オプションつけとく 

普段から Windows でコマンドでコピーすることなんてないのですが bat ファイル中でコピーしたいときはやっぱりコマンドからになります

コピーといえば copy コマンドですが Windows の copy コマンドはファイルをコピーするものです
フォルダをコピーするものではありません

フォルダをコピーするには xcopy や robocopy コマンドがあります
前にタイムスタンプもコピーしたい記事を書いたときには xcopy ではできないようだったので robocopy の紹介になりましたが 今回は xcopy を調べてみました


こんな構造のフォルダをサンプルとして使います
C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 0000001B 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d

オプション

オプション無し

オプションつけずにコピー元フォルダとコピー先フォルダを指定します
/F はコピー内容を詳細にに表示するためのものです
C:\Data\test-xcopy>xcopy a d /F
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\d\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\d\a2.txt
2 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 000000B5 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d
        a1.txt
        a2.txt

その階層のファイルだけがコピーされます
b や c フォルダはコピーされません

S オプション

S オプションをつけます
C:\Data\test-xcopy>xcopy a d /S /F
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\d\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\d\a2.txt
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\d\b\b1.txt
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\d\b\b2.txt
4 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 00000075 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d
    |   a1.txt
    |   a2.txt
    |
    \---b
            b1.txt
            b2.txt

b フォルダもコピーされました
S オプションがあると再帰的に 内側のフォルダもコピーされます
ただし c のような空のフォルダはコピーされません

E オプション

E オプションをつけます
C:\Data\test-xcopy>xcopy a d /E /F
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\d\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\d\a2.txt
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\d\b\b1.txt
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\d\b\b2.txt
4 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 000000B4 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d
    |   a1.txt
    |   a2.txt
    |
    +---b
    |       b1.txt
    |       b2.txt
    |
    \---c

E だと S に加えて空のフォルダもコピーします
エクスプローラの右クリックドラッグでコピーするのと同じにしたいなら E オプションです
(隠しファイルなどがある場合は後述の H オプションも必要です)

L オプション

L オプションをつけます
これは E などと一緒に使えます
C:\Data\test-xcopy>xcopy a d /E /L /F
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\d\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\d\a2.txt
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\d\b\b1.txt
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\d\b\b2.txt
4 File(s)

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 000000D7 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d

コピーメッセージは E と一緒ですが 実際にはコピーされていません
何がコピーされるのか確認するための機能です

T オプション

T オプションをつけます
これも他のオプションと組み合わせられます
C:\Data\test-xcopy>xcopy a d /T /F

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 00000063 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d
    \---b

b フォルダだけコピーされています
T オプションでは フォルダ構造だけをコピーしてファイルはコピーされません

c フォルダは中が空っぽなのでコピーされていません
コピーするには E オプションと組み合わせます
C:\Data\test-xcopy>xcopy a d /T /E /F

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 0000001B 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d
    +---b
    \---c

b と c フォルダがコピーされました

Q オプション

Q オプションをつけます
このオプションでは F オプションはいらないです
C:\Data\test-xcopy>xcopy a d /E /Q
4 File(s) copied

詳細なコピーした内容を一覧を表示しません
それでもコピー数は表示されるようです

その他

他にも

隠しファイルやシステムファイルもコピー
▶ /H

エラーがあっても続行
▶ /C

リンクはリンク先じゃなくてリンク自体をコピー
▶ /B

上書き確認する/しない
▶ /-Y, /Y

などは使うことがあるかもです


あとは

属性(AKM)や権限(XO) 暗号化ファイル(G) の扱い
読み取り専用なら(R) コピー先があれば(U) コピー
開始時(W)とファイル作成時(P)に確認メッセージ
コピー先の確認(V) 日付でコピーするか判断(D)
バッファ(J) ネットワークコピーのレジューム(Z)

などがあるみたい

存在しないところにコピー

これまではコピー先 d がありましたが 存在しない z を指定してみます
C:\Data\test-xcopy>xcopy a z /E /F
Does C:\Data\test-xcopy\z specify a file name
or directory name on the target
(F = file, D = directory)? d
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\z\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\z\a2.txt
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\z\b\b1.txt
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\z\b\b2.txt
4 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 0000002B 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
+---d
\---z
    |   a1.txt
    |   a2.txt
    |
    +---b
    |       b1.txt
    |       b2.txt
    |
    \---c

z はファイル名ですか?フォルダ名ですか? って聞かれました
a がフォルダなんだからフォルダって判断してくれないみたい

d を押してフォルダって教えてあげると ちゃんと z に a がコピーされました



f 押してファイルって言ったらどうなるの? と思ったのでやってみました
C:\Data\test-xcopy>xcopy a z /E /F
Does C:\Data\test-xcopy\z specify a file name
or directory name on the target
(F = file, D = directory)? f
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\z
Overwrite C:\Data\test-xcopy\z (Yes/No/All)? y
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\z
Overwrite C:\Data\test-xcopy\z (Yes/No/All)? y
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\z
Overwrite C:\Data\test-xcopy\z (Yes/No/All)? y
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\z
4 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 00000076 1234:5678
C:.
|   z
|
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
\---d

z はファイルです
中を見てみます
C:\Data\test-xcopy>type z
b2

それぞれのファイルにはファイル名を書いているので b2 と出ているということは b2.txt がコピーされたということです
コピー対象の最後のものがコピーされたようです

最後だけじゃなくて全部同じ名前 「z」 にコピーしていって 最終的には最後のファイル b2.txt で上書きされてこうなったのかも

I オプション

コピー元がフォルダなら自動でフォルダとして扱って欲しいと思ってましたが オプションでそういうものがありました

I オプションはコピー先がないときに コピーするものが複数あればコピー先をフォルダとみなしてくれるものです
C:\Data\test-xcopy>xcopy a z /I /E /F
C:\Data\test-xcopy\a\a1.txt -> C:\Data\test-xcopy\z\a1.txt
C:\Data\test-xcopy\a\a2.txt -> C:\Data\test-xcopy\z\a2.txt
C:\Data\test-xcopy\a\b\b1.txt -> C:\Data\test-xcopy\z\b\b1.txt
C:\Data\test-xcopy\a\b\b2.txt -> C:\Data\test-xcopy\z\b\b2.txt
4 File(s) copied

C:\Data\test-xcopy>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 0000009A 1234:5678
C:.
+---a
|   |   a1.txt
|   |   a2.txt
|   |
|   +---b
|   |       b1.txt
|   |       b2.txt
|   |
|   \---c
+---d
\---z
    |   a1.txt
    |   a2.txt
    |
    +---b
    |       b1.txt
    |       b2.txt
    |
    \---c

確認が出ないでにコピーされています

ファイルのコピー

次はファイルのコピーをしてみます
a\b のフォルダの中に移動します
C:\Data\test-xcopy>cd a\b

C:\Data\test-xcopy\a\b>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 00000004 1234:5678
C:.
    b1.txt
    b2.txt

No subfolders exist

コピー先がファイル場合

コピー先にファイルがある b2.txt という名前でコピーします
C:\Data\test-xcopy\a\b>xcopy b1.txt b2.txt
Overwrite C:\Data\test-xcopy\a\b\b2.txt (Yes/No/All)? y
C:b1.txt
1 File(s) copied

C:\Data\test-xcopy\a\b>type b2.txt
b1

上書きするか確認が出て y を押すと上書きされます

コピー先がフォルダの場合

次にフォルダの場合です
mkdir で f フォルダを作ります
C:\Data\test-xcopy\a\b>mkdir f

C:\Data\test-xcopy\a\b>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 00000080 1234:5678
C:.
|   b1.txt
|   b2.txt
|
\---f

フォルダ f にファイルをコピーします
C:\Data\test-xcopy\a\b>xcopy b1.txt f
C:b1.txt
1 File(s) copied

C:\Data\test-xcopy\a\b>tree /A /F
Folder PATH listing for volume Windows
Volume serial number is 000000A7 1234:5678
C:.
|   b1.txt
|   b2.txt
|
\---f
        b1.txt

この場合は何もメッセージが出ずにフォルダの中にコピーできました

コピー先が存在しない場合

コピー先が存在しない b3 とします
C:\Data\test-xcopy\a\b>xcopy b1.txt b3
Does b3 specify a file name
or directory name on the target
(F = file, D = directory)? F
C:b1.txt
1 File(s) copied

C:\Data\test-xcopy\a\b>type b3
b1

コピー元がファイルの場合でも コピー先がファイルかフォルダか聞かれます
ファイルにすると普通にコピーされます


じゃあフォルダにしたら?
C:\Data\test-xcopy\a\b>xcopy b1.txt b3
Does b3 specify a file name
or directory name on the target
(F = file, D = directory)? D
C:b1.txt
1 File(s) copied

C:\Data\test-xcopy\a\b>type b3\b1.txt
b1

b3 というフォルダができてその中に b1.txt がコピーされました


I オプションみたいなもので コピー元がファイルならコピー先もファイルと扱うオプションがありそうですが 見当たりませんでした
I オプションは複数なら フォルダとみなすものなので この場合には効果なしです
C:\Data\test-xcopy\a\b>xcopy b1.txt b3 /I
Does b3 specify a file name
or directory name on the target
(F = file, D = directory)?

通常のファイルコピーなら xcopy でなく copy コマンドを使えということでしょうか

最後に

「xcopy /?」 のヘルプが全部英語で読むのめんどくさいなーと思いつつも試していたのですが 後でコピー漏れがあって別のパソコンで試すと日本語でした……

原因は最初に試していたパソコンではデフォルトが chcp 65001 になってたからでした
エラーメッセージみたいなのは英語でもいいですけど 説明の長文はやっぱり日本語の方がいいです