Powershell重複しないファイル名の生成

コンピュータ

はじめに

Windowsのエクスプローラでフォルダを作成すると「新しいフォルダー」が出来上がります。
続けてフォルダを作成すると「新しいフォルダー(2)」というフォルダが出来ます。
2回目のフォルダ作成時「新しいフォルダー」が既に存在しているので、重複しないパスにする為「(2)」となります。Powershellスクリプトでファイルを取扱っていると同様な場面に出会うことが多々ございますので、重複しないファイル名の生成をしてみたいと思います。

PowerShellスクリプトを初めて実行する場合

PowerShellスクリプトの実行を許可してください。
Powershellのps1ファイルを実行する方法
PowersehllをはじめるにあたりWindowsのコマンドラインインターフェースであるPowershellはコマンドレットと言われる命令をテキストファイルに記述したスクリプトファイルを実行することが出来ます。Powershellはその名...

ファイルの存在確認

まずは指定するファイルが存在しているか確認する命令を試してみます。

Test-Path -Path "ファイルのパス"

このコマンドレットはファイルのパスが既に存在する場合True(真)存在しないFalse(偽)を返します。
スクリプトを組む場合はこちらの結果をIf文などで条件分岐することになります。

if (Test-Path -Path $Target-Path) {
  echo ($Taget-Path + "は存在する")
} else {
  echo ($Taget-Path + "は存在しない")
}

ファイル番号のカウントアップのループ処理

一定条件を満たすまでループする処理を行います。ループの構文は複数有りますが今回はFor文を使います。

for($i  = 0; (継続条件); $i++) {
    # 処理
}

この処理は(継続条件)が成立(真)するかぎり{}内の処理を実行します。
この際$i変数は”$i=0″で初期化され”$i++”でカウントアップされます。
一般的な(継続条件)の式は”$i -lt 10″(10以下)などとすると0~9まで10回ループします。

今回は決まった回数をループするのではなくファイル名の重複が解消されるまでループする事になります。

ファイル名のベース名と拡張子を取得

連番ファイル名を生成する為にはファイル名を以下の様にフォーマットする必要があります。
“ベース名” ( 連番 ) “.拡張子”
さらにそのファイルが存在するフォルダのパスも必要となります。
Powershellのファイルオブジェクトのプロパティから取得します。

$f = Get-Item "ファイルのパス";
echo $f.BaseName # ベース名
echo $f.Extension # 拡張子
echo $f.Directory.FullName # フォルダパス

 

関数について

重複しないファイル名を生成するための材料はそろいました。
この材料を組み合わせてルーチン化しますが、そのルーチンを何度も実行することになりますので関数化することとします。
関数の書式は次のように成ります。

function 関数名 (変数)
{
  return 戻り値
}

Powershell独特の書き方もありますが、一般的なプログラミング言語ぽい書き方になります。

空のファイル名作成

今回のルーチンが正しく動作するか確認するため、空ファイル(ファイルサイズ0)の作成します

New-item -type file <ファイルのパス>

スクリプト

一連の処理をスクリプトにまとめます。
メモ帳などで以下のコードを入力しファイル名を「Create-UniquePath.ps1」で保存します。
ファイル名:Create-UniquePath.ps1

<#
.SYNOPSIS
 重複しないファイル名を生成

.EXAMPLE
 PS > Create-UniquePath.ps1
#>
function Create-UniquePath($basePath)
{
    # 存在しない場合お帰りいただく
    if (!(Test-Path -LiteralPath $basePath))
    {
        return $basePath
    }

    $f = Get-Item $basePath;
    $result = $basePath;
    for($i=1; (Test-Path -Path $result); $i++)
    {
        $fileName = ("{0}({1}){2}" -f $f.BaseName, $i, $f.Extension)
        $result = Join-Path $f.Directory.FullName $fileName
    }
    return $result
}

# 関数のテスト実行
$r = Create-UniquePath ".\Create-UniquePath.ps1"
echo (New-item -type file $r)

実行するごとに”Create-UniquePath(n).ps1″形式のファイルが出来上がれば成功です。

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020/04/29      9:52              0 Create-UniquePath(1).ps1

コメント