【PowerShell】ファイル名の先頭に文字列を一括追加するコマンド
ExcelやWordでは開いているファイルと同名のファイルを開くことができないため、ソースとターゲットをうっかり同時に開こうとしたときなどにもやっとすることがあります(PowerPointはなぜか開けます)。
このような場合はどちらか片方をリネームすることになるのですが、先日、このリネームを大量に行いたいとの要件があり、スクリプトを考えました。
少しハマったので、覚え書きを兼ねて共有させていただきます。つたない内容ですがご容赦ください。
リネームの内容
ディレクトリ内にある各ファイルの先頭に「x_」を追加するというシンプルなリネームです。
元のファイルのファイル名は「1234567_nn.xlsx」という形式で、「nn」には01~30の数字が入ります。
MS-DOSのrenコマンドの制約
MS-DOSでディレクトリに移動し、何も考えずにrenコマンドを実行してみました。
ren *.xlsx x_*.xlsx
次のようになりました。
冒頭にあった「1234567」の「12」が上書きされてしまっています。
調べたところ、renコマンドには「元のファイル名の文字数を保持する」という制約があり、今回のリネームには不向きであることがわかりました。
PowerShellのrenameコマンドを試す
次の方法を考えました。batを作成したりVBAでプログラムを組んだりしたらいくらでも対応できそうですが、作る時間が割に合わないように思い、同じコマンドベースのPowerShellを検討しました。
PowerShellにもrenameコマンドが用意されていました。幸い、文字数を保持するような制限はないようでした。
このコマンドのパラメータではワイルドカードを使えないようなので、次のコマンドを実行してみました。
dir | rename-item -newname { $_.name -replace '1234567','x_1234567' }
今度は実行が終わらなくなりました。Ctrl+Cで止めてディレクトリを確認してみると、大変なことになっていました。
リネームが‥再帰的に‥!?
PowerShellのrenameコマンドを工夫する
最終的に次のコマンドでうまく実行できました。
dir | rename-item -newname { $_.name -replace '\A1234567','x_1234567' }
「\A」は先頭文字を示す正規表現です。
renameコマンドの再帰処理について
実は、この記事を書くにあたってこの現象を確認しようとしたら、再現しませんでした。
驚いて少し検証してみたところ、私の環境ではリネーム対象のファイル(もしくはリネーム回数?)が20件を超えると再帰処理になるらしく、19ファイル以下ではさらっと完了してくれました。
もしこの再帰に遭遇した方がいて、正規表現ではうまく切り分けられないようなリネームを行いたい場合、ディレクトリ内のファイルの件数を減らしてみるとうまくいくかもしれません。
参考記事
追記
PowerShell3.0で報告されていたこちらの現象のようです。私の環境のPowerShellは5.1なので、どうやら直されていないようですね。