Windows PowerShellでファイル名を一括変更する(Get-ChildItemとRename-Itemを使用)

2022/01/13
数年の沈黙を破り,このWikiを更新します.非公開のWikiばかり更新していたのですが,公開できる記事を少しずつ公開していくつもりです.
第1弾はWindows PowerShellでのファイル名一括置換操作.私がPowerShellのコマンドで使うもの上位です.

リネームソフトは世の中にたくさんあると思いますが,Windows環境で何も準備せずに使えてパワフルなので気に入っています.
ただし,よくわかってないところがあります.使えてるからいいか,くらいの認識でいるので,ご使用の際は注意してください.

説明

概要

Windows PowerShell上で正規表現を使ったファイル名の一括置換を行いたい場合,次の書式でコマンドを入力する.
Get-ChildItem -r 「パス」 | Rename-Item -NewName { $_.Name -replace 'Old','New' }
入力の例.これはカレントディレクトリ以下のファイルの変更を行いたい場合である.
> Get-ChildItem -r . | Rename-Item -NewName { $_.Name -replace '0405','0404' }
意味はファイル名に『0405』という文字列が含まれている場合,それをすべて『0404』に置換するというもの.

注意点

正規表現の書式
第一引数(元となる文字列,上の'Old')は正規表現に則ったエスケープが必要だが,第二引数(新しい文字列,上の'New')はエスケープを書くと逆にエラーになる*1
PS C:\Users\user\Desktop\Renamed\○○○○> Get-ChildItem -r C:\Users\user\Desktop\Renamed\○○○○\* `
| Rename-Item -NewName { $_.Name -replace '(X\+092_Y\+092)', 'X-095_Y\+092_moto\($1\)'}
Rename-Item : 指定された対象がパスまたはデバイス名を表しているため、名前を変更できません。
発生場所 行:1 文字:98
+ Get-ChildItem -r C:\Users\user\Desktop\Renamed\○○○○\* | Rename-Item <<<<
  -NewName { $_.Name -replace '(X\+092_Y\+092)', 'X-095_Y\+092_moto\($1\)'}
    + CategoryInfo          : InvalidArgument: (:) [Rename-Item]、PSArgumentException
    + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand

PS C:\Users\user\Desktop\Renamed\○○○○>
PS C:\Users\user\Desktop\Renamed\○○○○> Get-ChildItem -r .\* | Rename-Item -NewName { $_.Name -replace '(X\+092_Y\+092)', 'X-095_Y+092_moto($1)'}
PS C:\Users\user\Desktop\Renamed\○○○○>
Get-ChildItemのパス指定部
Get-ChildItemのパス指定部は絶対パスでも相対パスでもよいが,何かをきっかけに変なエラーが出る.
Rename-Item : ソース パスとターゲット パスを同じにすることはできません。
これを完全に回避する方法はよくわからない.
パスの最後を「*」にしてカレントディレクトリに入ってコマンドを入力したり,
考え付く範囲でパス指定やファイル名を変更すると通ることがあるようだ.

*1 : 以下の例は仕事で使った処理(文字列)を公開しても良い文字列に手動で書き換えて,表示結果を推測しています.挙動が違う可能性もあるので注意してください.