5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【PowerShell】特定のファイルをディレクトリ構造を維持したままコピーする(Robocopyを利用して)

Last updated at Posted at 2019-06-29

やりたいこと

  • ディレクトリ構造を維持した状態で、指定ファイルを別ディレクトリに移動させる

TL,DR

  • コピー元にファイルを指定したとき、ディレクトリ構造を維持するのにCopy-Itemは使いにくさを感じた。
  • Robocopy.exeを使う。
  • ファイルは第三引数に指定する。
  • ディレクトリ構造を維持するには、コピー対象のファイルに対するコピー元とコピー先の親ディレクトリを合わせる必要がある。

:sunny: ファイルのみをコピーする際にCopy-Itemではディレクトリ構造を維持するのが困難(主原因:自分のぐぐり力)

見出しの通りです。
こういうスクリプトを書いたりしてました。(失敗)

copyItem.ps1
PS> Copy-Item .\test1\level1\index.html .\test2 -Recurse -Container

:sunny: 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

:sunny: ファイルは第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行目とかを見ていただくとわかると思いますが、ファイル名のあとにバックスラッシュが入ってます。
第一引数、第二引数はともにディレクトリを指定しましょう
(※第三引数には、ファイル名のみ指定します。)

:sunny: コピー対象のファイルに対する、コピー元・先の親ディレクトリを合わせる

コピー後の理想を下記とした場合
.\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のページに飛びます。

参考

雑記

サイトの保守作業で、作業後に、修正を加えたファイルのみを別ディレクトリに置くためにこういうスクリプトを書きたいなと思った次第なのでした。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?