none
フォルダAからフォルダBへのファイル移動 RRS feed

  • 質問



  • フォルダAから構造の異なるフォルダBにファイル移動を実現させたいと考えています。
    フォルダAとフォルダBの紐づけは以下のようにおこない、想定した場所にファイルを移動させたいです。

    上記を実現させる場合どのような記述をする必要があるでしょうか?
    お力添えいただれば幸いです。


    ■マッピング
     【フォルダA】                        【フォルダB】
    ①フォルダ:1A ─────────── フォルダ:1A001X_1A1001
    フォルダAのファイル名「1A」がフォルダBのフォルダ名後半部分「1A****」に含まれているかを判断

    ②ファイル:1A_X_20191018 ──── フォルダ:1A001X_1A1001
    フォルダAのファイル名プレフィックス「1A」と「X」がフォルダBのフォルダ名前半部分「1A***X」に含まれているかを判断

    ■各フォルダ構成
      フォルダ:A
       └─フォルダ:1A
       │   └─ファイル:1A_X_20191018
       │     └─ファイル:1A_Y_20191018
       │   └─ファイル:1A_Z_20191018
       │ 
       └─フォルダ:1B 
       │   └─ファイル:1B_X_20191018
       │   └─ファイル:1B_Y_20191018
       │ 
       └─フォルダ:1C 
          └─ファイル:1C_X_20191018

      フォルダ:B 
       └─フォルダ:1A001X_1A1001
       │   └─ファイル:1A_X_20191018
       │     
       └─フォルダ:1A001Y_1A2001
       │   └─ファイル:1A_Y_20191018
       │ 
       └─フォルダ:1A001Z_1A3001 
       │  └─ファイル:1A_Z_20191018
       │     
       ・
       ・

    よろしくお願いいたします。





    • 編集済み Lopez0312 2019年10月18日 7:02
    2019年10月18日 3:37

回答

  • Lopez0312様

    失礼しました。
    修正しましたので、ご確認ください。

    うっかりミスでMove-Itemすると消えてしまったり意図しない場所に移動したりするので、 Whatif の結果をご確認の上、問題ないようでしたら -whatif を外してお試しください。

    「"1A_X_Z"というファイル名があった場合にも1A001X_1A1001に移動する」ということであれば、修正しなくてもそのまま動くはずです。もし「1A_X_Z_**** のときは~というフォルダに…」のようにしたいのであれば

    $Column3 = ($a.Name -Split "_")[2]

    のようにして、$DestFolderPathを作る際に $Column3 の状態で条件分岐させればよいと思います。



    • 編集済み やき(Yaki) 2019年10月21日 7:23 コピー先に Z はないのでPetternから削除
    • 回答としてマーク Lopez0312 2019年10月23日 5:09
    2019年10月21日 7:17

すべての返信

  • >①フォルダ:1A ─────────── フォルダ:1A001X_1A1001
    >フォルダAのファイル名「1A」がフォルダBのフォルダ名後半部分「1A****」に含まれているかを判断

    前半と後半はアンダースコアで区切られるということで良いですね?
    文字列に対し-Split で任意のデリミタを指定して文字列配列に分割できますので、

    $Array = $Name -Split "_"

    とすれば、$Array[1]が後半部分になります。

    また、文字列$Aの中に文字列$Bが含まれているかは、$A.Contains($B)で調べられます。

    単に「含まれる」ではなく、アンダースコアに続く場合に限るといった決まりがある場合は、-Match 演算子で正規表現を使うこともできます。

    なお、Get-ChildItem でフォルダやファイルの一覧を変数(配列)に代入して ForEach で回したり、If による条件分岐はお分かりですよね?

    念のため、フォルダだけ取得するのは

    Get-ChildItem | ?{$_.PSIsContainer}

    です。

    2019年10月19日 11:39
  • その例だと、A配下のフォルダ名は全く関係なく、単にファイル名の前半4文字をフォルダBに紐づけているように見えますが、いかがでしょうか。

    であれば、以下のように正規表現を使って、HITするフォルダに移動すればいいと思います。
    もしフォルダ名も関係するようであれば、下記例のColumnを増やして Pettern を修正すれば対応できると思います。

    $FolderA = "D:\A"
    $FolderB = "D:\B"
    
    # 全部のファイル検索
    $SrcFile = Get-ChildItem -Path $FolderA -Recurse -File
    
    # 移動先のフォルダ一覧
    $DestFolderList = Get-ChildItem -Path $FolderB -Recurse -Directory
    
    Foreach($a in $SrcFile)
    {
    	# 例えば ファイル:1A_X_20191018 なら
    	$column1 = ($a.Name -Split "_")[0] # 1A が入る
    	$column2 = ($a.Name -Split "_")[1] # X が入る
    	
    	# 移動先を探す
    	# 移動先はすでに作成されており、
    	# 1A001X_1A1001 と 1A001X_1A2001 のように複数HITする場合は最初のもの採用
    	$Pattern = "^$($Column1)[0-9]{3}$($Column2)_"
    	$DestFolderPath = $DestFolderList | ?{$_.Name -match $Pattern} | Select -Expand FullName -First 1
    	
    	Move-Item -LiteralPath $a.fullname -Destination $DestFolderPath -whatif
    }

    編集(2019/10/21 16:08):
    ・Patternの修正
    ・Move-Item にWhatifの追加

    Whatifの結果に問題がないようでしたら、Whatifを外して実行してください。

    • 編集済み やき(Yaki) 2019年10月21日 7:10 -match 条件の追加と修正
    2019年10月21日 2:24
  • やき様


    回答ありがとうございます。
    試してみましたが「'-match' 演算子に続けて値の式を指定する必要があります。」というエラーが表示されます。
    この場合、何を追記したら良いのでしょうか?


    また、「1A_X _Z」というファイル名もある場合
    columnを追加して、$Patternに加えることで対応できますでしょうか?


    以上、よろしくお願いいたします。
    2019年10月21日 6:36
  • Lopez0312様

    失礼しました。
    修正しましたので、ご確認ください。

    うっかりミスでMove-Itemすると消えてしまったり意図しない場所に移動したりするので、 Whatif の結果をご確認の上、問題ないようでしたら -whatif を外してお試しください。

    「"1A_X_Z"というファイル名があった場合にも1A001X_1A1001に移動する」ということであれば、修正しなくてもそのまま動くはずです。もし「1A_X_Z_**** のときは~というフォルダに…」のようにしたいのであれば

    $Column3 = ($a.Name -Split "_")[2]

    のようにして、$DestFolderPathを作る際に $Column3 の状態で条件分岐させればよいと思います。



    • 編集済み やき(Yaki) 2019年10月21日 7:23 コピー先に Z はないのでPetternから削除
    • 回答としてマーク Lopez0312 2019年10月23日 5:09
    2019年10月21日 7:17