明日は我が身の備忘録(あすびぼ)

自分向け備忘録です。頻繁に更新は難しいでしょうね

Powershellで複数のファイル名を変更するスクリプトを作成

 データ管理等を行う際にフォルダ名に月日をMMDDのように記述していたが、年の文字を入れていなかったので年を跨いでしまってフォルダ名でソートすると時系列順にならない。

 フォルダ名の先頭に年の数値を入れればこの問題は解決するが、フォルダ数が数十、数百あると手で変更するのが非常に面倒。そこでWindowsで標準にある、PowerShellでフォルダ名に年の数値を入れるスクリプトを作成する。

f:id:kirikoshokunin:20210404015742p:plain:w200

先頭に年を追加するPowerShell スクリプト

 今回は、下のようなスクリプトを作成した。PowerShellで名前を変更したフォルダがあるディレクトリまで移動して実行すると、すべてのフォルダの先頭に20という文字が追加される。21年のときは$year = "21"とすればよい。

非常に簡単なスクリプトなのでディレクトリまで手動で移動した、すべてのフォルダ名を変更するので運用は慎重に行う必要がある。

スクリプトの実行

 スクリプトの実行方法は複数あるが今回は、ディレクトリを名前を変更したいフォルダまで移動する必要がある。この場合便利なのが PowerShell ISE だ。これはPowerShellスクリプトの開発環境でスクリプトデバッグの為にステップ実行などもできる。

 PowerShell ISEのコマンドプロンプトで名前を変更したいフォルダがあるディレクトリまで移動して、スクリプトを開いて実行する。

f:id:kirikoshokunin:20210404015914p:plain:w300
PowerShell ISEで実行

f:id:kirikoshokunin:20210404012826p:plain:w300
スクリプト実行前のフォルダ名

f:id:kirikoshokunin:20210404020043p:plain:w300
スクリプト実行後のフォルダ名

 

スクリプトが実行できない場合は実行ポリシーを変更する必要があるかもしれない。

kirikoshokunin.hatenablog.com

スクリプト説明

変数宣言
[string]$year = "20"  #追加する文字を記入

 まず一行目の文だが、ここで追加する文字を宣言している。この場合は20が追加する文字となる。yearが変数名でその前の[string]で文字列と明示している。

Get-ChildItem
Get-ChildItem -Path . -Directory | foreach{ #カレントディレクトリのフォルダ数の分だけ繰り返す

Get-ChildItem'' はカレントディレクトのすべての項目のファイル名等を読み出すというコマンドでUNIXのls``と同等。 このコマンドだけを実行すると下の画面のようになる。

f:id:kirikoshokunin:20210404012650p:plain:w200
Get-ChildItemの実行結果

一番左の列から、それぞれのファイルの属性を示し、最終更新日、ファイル容量、ファイル名の順になっている。

属性の意味はざっくり下の表のようになっている。

d ディレクト ファイルのこと
a アーカイブ Windowsシステムがバックアップ判別に使用
r 読み取り専用 プロパティとかで読み取り専用フォルダとしたもの
h 隠しファイル 通常はエクスプローラーに表示されないファイル
s システムファイル 通常はユーザが操作しないファイル

またGet-ChildItem''にはオプションを付けることができる。 今回は-Pathという オプションを使用している。このオプションは探すディレクトリを指定するもので、Get-ChildItem -Path .\122012`` と入力して実行すると下画像のように 122012ファイル の中身が見れる。ちなみ、カレントディレクトを見るなら省略可能。

f:id:kirikoshokunin:20210404012257p:plain:w200
Get-ChildItemパス指定

また、オプションをさらにつけ-Directoryを追加するとフォルダのみを一覧表示する。

Get-ChildItem -Path . -Directory

f:id:kirikoshokunin:20210404012826p:plain:w200
Get-ChildItem -Path . -Directory実行結果

foreach

foreachは繰り返し処理を行う処理に用いる。通常は下のように(変数 in 配列 )のような反復処理する変数と順次変数に代入する配列の記述がくっついている。

shell $letterArray = "a","b","c","d" foreach ($letter in $letterArray) { Write-Host $letter }

about_Foreach - PowerShell | Microsoft Docsから引用

 しかし今回は、下のように()がないこれはforeachにGet-ChildItemの結果を与えているからだ。結果はループの中でフォルダ名は$_.Nameで読むことができる。

Get-ChildItem -Path . -Directory | foreach{  }

 

 よって下の処理は変数$new_nameに以前宣言した変数&yearに今のファイル名を追加するという処理になる。PowerShellでは文字列でも+で足し合わせることができる。 また足し算の順番で文字列で足されるので、$_.Name + $yearとするとファイル名の最後に"20"が追加される。

$new_name = $year + $_.Name       #アイテムの名前を取得して年数を頭に追加 
Rename-Item

 そしてファイルやフォルダの名称を変更するには、Rename-Itemを使用する。これは下のように使用する。

Rename-Item $今のファイル名 -NewName $新しいファイル名

今回はforeachで繰り返し処理をしているので、$_を使用すると今回のループで代入されているファイルを参照することになる。