やりたいこと
- ディレクトリ構造を維持した状態で、指定ファイルを別ディレクトリに移動させる
TL,DR
コピー元にファイルを指定したとき、ディレクトリ構造を維持するのにCopy-Item
は使いにくさを感じた。-
Robocopy.exe
を使う。 - ファイルは第三引数に指定する。
- ディレクトリ構造を維持するには、コピー対象のファイルに対するコピー元とコピー先の親ディレクトリを合わせる必要がある。
ファイルのみをコピーする際にCopy-Item
ではディレクトリ構造を維持するのが困難(主原因:自分のぐぐり力)
見出しの通りです。
こういうスクリプトを書いたりしてました。(失敗)
PS> Copy-Item .\test1\level1\index.html .\test2 -Recurse -Container
Robocopy.exe
を利用する
今回の目的を達成するためにぐぐってるとRobocopy
を使うという記事がいくつかヒットしました。
(**"copy-item ファイル ディレクトリ構造 維持"とか"copy-item file directory structure"**とかでググりました。)
そもそも、ファイルではなくディレクトリごをそのままコピーする場合なら先述のCopy-Item
のオプション-Recurse
を付ければ実現可能です。
しかしながら今回は、どうしてもファイルのみをコピーしたかったので...。
Robocopy
に関してはググればたくさん記事が出ます。
こういうスクリプトを書きました。
/E
でサブディレクトリのコピー
2020.05.29 追記:コピー対象がファイルのみの場合、このオプションは不要です。似たようなオプションに、/S
がありますがそれも同様です。
/R:n
でコピー実行時、エラーが起きた場合の再実行回数を指定(今回は1
を指定)
Robocopy.exe $fromDirectoryPath $destinationDirectoryPath $fileName /R:1
ファイルは第3引数に指定する
コピー先やコピー元にファイル名を入れるとうまく行きません。
(実行結果はちなみにこんな感じになります。)
PS> Robocopy.exe .\test1\level1\index.html .\test2 /E
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : 2019年6月29日 16:37:51
Source : C:\Users\username\test1\level1\index.html\
Dest : C:\Users\username\test2\
Files : *.*
Options : *.* /S /E /DCOPY:DA /COPY:DAT /R:1000000 /W:30
------------------------------------------------------------------------------
2019/06/29 16:37:51 ERROR 123 (0x0000007B) Accessing Source Directory
C:\Users\username\test1\level1\index.html\
The filename, directory name, or volume label syntax is incorrect.
下から2行目とかを見ていただくとわかると思いますが、ファイル名のあとにバックスラッシュが入ってます。
第一引数、第二引数はともにディレクトリを指定しましょう。
(※第三引数には、ファイル名のみ指定します。)
コピー対象のファイルに対する、コピー元・先の親ディレクトリを合わせる
コピー後の理想を下記とした場合
.\test2\level1\index.html
以下の書き方ではうまく行きません。
PS C:\Users\username> Robocopy.exe .\test1\level1 .\test2 index.html /E
実行します。
PS C:\Users\username> Robocopy.exe .\test1\level1 .\test2 index.html /E
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : 2019年6月29日 16:40:58
Source : C:\Users\username\test1\level1\
Dest : C:\Users\username\test2\
Files : index.html
Options : /S /E /DCOPY:DA /COPY:DAT /R:1000000 /W:30
------------------------------------------------------------------------------
1 C:\Users\username\test1\level1\
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 1 0 1 0 0 0
Files : 1 0 1 0 0 0
Bytes : 248 0 248 0 0 0
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Ended : 2019年6月29日 16:40:59
コピー自体は成功です。
肝心のコピー先のディレクトリを見てみますと、、
PS C:\Users\username> ls .\test2
ディレクトリ: C:\Users\username\test2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019/06/29 15:28 248 index.html
ディレクトリ構造が維持されていません。
なので、先ほどのスクリプトを修正します。
PS C:\Users\username> Robocopy.exe .\test1\level1 .\test2\level1 index.html /E
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : 2019年6月29日 16:54:03
Source : C:\Users\username\test1\level1\
Dest : C:\Users\username\test2\level1\
Files : index.html
Options : /S /E /DCOPY:DA /COPY:DAT /R:1000000 /W:30
------------------------------------------------------------------------------
New Dir 1 C:\Users\username\test1\level1\
100% New File 248 index.html
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 1 1 0 0 0 0
Files : 1 1 0 0 0 0
Bytes : 248 248 0 0 0 0
Times : 0:00:00 0:00:00 0:00:00 0:00:00
Speed : 49600 Bytes/sec.
Speed : 2.838 MegaBytes/min.
Ended : 2019年6月29日 16:54:03
結果は以下のとおりです。
PS C:\Users\username> ls .\test2 -Recurse
ディレクトリ: C:\Users\username\test2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2019/06/30 0:06 level1
ディレクトリ: C:\Users\username\test2\level1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019/06/30 0:06 0 index.html
うまくいきました。
スクリプト
※Gistのページに飛びます。
参考
雑記
サイトの保守作業で、作業後に、修正を加えたファイルのみを別ディレクトリに置くためにこういうスクリプトを書きたいなと思った次第なのでした。