Windowsバッチのファイル移動で、同名ファイルが存在していた場合、上書きではなく連番付与したい – windows バッチ

質問:


最終的にやりたいこと
・対象フォルダ(サブフォルダ含む)内にある特定拡張子ファイルのみ、指定フォルダへ移動したい
・同名ファイルが存在していた場合、上書きではなく連番付与したい


試したこと
特定ファイルを指定フォルダに一括移動させるバッチファイルで移動確認は出来たのですが、同名ファイルが存在していた場合、1ファイルに上書きされてしまいます


Q
・同名ファイルが存在していた場合、上書きではなく連番付与する、条件追加が分かりません
・同名ファイルが存在していた場合の条件分岐はどの段階で追加する? list.txt作成する時? それとも、ファイルを1行ずつ処理する時?

質問者: re9

同名ファイルが存在していた場合の条件分岐はどの段階で追加する? list.txt作成する時? それとも、ファイルを1行ずつ処理する時?

list.txt作成時に条件分岐を加えると、ファイル作成前に新規作成された場合上書きされますので、処理する時に追記するべきだと思います。

同名ファイルが存在していた場合、上書きではなく連番付与する、条件追加が分かりません

Powershellの方が連番の取得など細かい操作に向いているので、Powershellで実装例を作ってみました。

# 変数を変更して実行すること
Move-Mp3 -Path "D:testsrc" -Dest "D:testdst" -IsMove $false

<#
.SYNOPSIS
 指定フォルダ以下のファイルを移動またはコピーし、移動先に同名ファイルが存在する場合は連番を付加する

.DESCRIPTION
 指定された移動元フォルダから特定拡張子のファイルを再帰的に取得して、指定された出力先に移動またはコピーする。
 出力先に同名ファイルが存在する場合は連番を付加して上書きを回避する。
 移動元フォルダの構成は再現せず、出力先フォルダ直下に直接移動またはコピーを行う。

.PARAMETER Path
 移動元フォルダのパス。

.PARAMETER Dest
 移動またはコピーする出力先フォルダのパス。

.PARAMETER Filter
 ファイル名や拡張子などのフィルタ。
 省略時は"*.mp3"

.PARAMETER IsMove
 $trueの場合は移動、$falseの場合はコピーを行う。
 省略時は移動する

.NOTES
 出力先フォルダが存在しない場合はエラーとなる。

#>
function Move-Mp3 {
    Param(
        [parameter(mandatory=$true)][String]$Path,
        [parameter(mandatory=$true)][String]$Dest,
        [String]$Filter = "*.mp3",
        [bool]$IsMove = $true
    )

    ls -Path $Path -Filter $Filter -Recurse | foreach {
      $src = $_.FullName
      $name = $_.Name
      $target = "${Dest}${name}" 
      while (Test-Path $target) {
        $f = [System.IO.Path]::GetFileNameWithoutExtension($name)
        $x = [System.IO.Path]::GetExtension($name)
        $r = [regex]"^(.*?)([0-9]+)$" 
        $m = $r.Match($f)
        if($m.Success) {
          # 末尾の数値をカウントアップ
          $index = [int]$m.Groups[2].Value + 1
          $name = "{0}{1}{2}" -f $m.Groups[1].Value, $index, $x
        } else {
          # 末尾に数値がなければ拡張子の前に"-1"を追加
          $name = "{0}-1{1}" -f $f, $x
          $index++
        }
        $target = "${Dest}${name}" 
      }
      if($IsMove) {
        move $src $target
        "$src を $target に移動しました。"
      } else {
        copy $src $target
        "$src を $target にコピーしました。"
      }
    }
}

当初はbatファイルで実装しようとしましたが、連番の抽出などが面倒で挫折しました。
中途半端な実装例でもbatファイルを見たい場合は、履歴から修正前の回答をご参照ください。

出典

You Might Also Like

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です