適材適所

WindowsやPowerShellやネットワーク、IBMなどのシステム系の話など気になったことも載せているブログです。

【Rename-Item】ファイルやフォルダ名を変更する【PowerShell】

yyyy-mm-dd形式 VS yyyymmdd形式 VS・・・

ファイルサーバーを覗いてみると、

20210102〇〇.xlsx 20200702〇〇.txt

また別のフォルダを覗いてみると、

2020-10-11〇〇.txt 2017-08-22〇〇.pdf

バラバラな表記。

ファイルやフォルダが作られた日付を判別するためにファイルの頭に年月日を付ける人も多いかと思います。

私はyyyymmdd_で統一する派ですが、yyyy-mm-dd の人もいます。

また、yymmdd-派の人もいます。

フォルダの中では統一されていることがほとんどですが別のフォルダを見ると違う形式だったりとみんなバラバラなんてことも。

また、ファイルサーバを運用していると、〇〇BOOKと〇〇Bookであったり、()と()であったりと同じようなファイル名に見えて、微妙に表記がゆれていることがあります。

この状態ってなんとなく気持ち悪い・・・。表記を統一したい・・・。

でも、いちいち手動で統一するのは大変。

そんなときはPowerShellの力を借りて一発で統一してしまいましょう。

Rename-Itemコマンドレット

そんなときに活躍するのが、Rename-Itemコマンドレットです。

Rename-Itemコマンドレットは読んで字のごとく、名前を付け直すためのコマンドレットです。

使い方はとっても簡単。

PS > Rename-Item -Path '.\old.txt' -NewName 'new.txt'

この例では、old.txtをnew.txtに変名しています。

-Pathで変名したいファイルパスを指定して、-NewNameで新しい名前を指定します。

このコマンドレットの便利なところは、対象のパスをパイプで受け取れるところです。

それを利用すれば名前を変えたいファイル名やフォルダ名がたくさんあってもワンライナーで変換することができます。

また、正規表現を使えば柔軟に名前を変更することができます。

ファイル名やフォルダ名を一括で変更する

yyyy-mm-ddをyyyymmddに変更する

例えば、yyyy-mm-ddという接頭辞をyyyymmddに変更するときは、正規表現を組み合わせることで次のように書くことができます。

 
Get-ChildItem -Recurse |Wherer-Object{$_ -match '^((\d{4})-(\d{2})-(\d{2})_)(.*)'}|Rename-Item -NewName ('{0}{1}{2}_{3}' -f $Matches[2],$Matches[3],$Matches[4],$Matches[5])

正規表現と組み合わせてファイル名を変換しています。

$Matches変数はPowerShellの自動変数の1つで、-match演算子によって正規表現のチェックが行われたときに、一致した部分が格納されます。

上記の例ではさらに正規表現を使の中で抽出したい部分を()で括っているので、それらの一致も$Matches変数に格納されます。

^((\d{4})-(\d{2})-(\d{2}))(.*) の部分が正規表現ですが、\dは数字を表しており、この正規表現は、「数字4つ-数字2つ-数字2つそれ以外」という意味になります。

さらに各数字の部分とそれ以外を()で括っているので、これらも$Matches変数に格納されます。

Rename-Itemの-NewNameで使う、新しいファイル名はこの$Matches変数に格納された各数字と、それ以外の文字を使って組み立てます。

最終的なファイル名はさらに、文字列書式と-f演算子を使って組み立てています。

yyyymmdd形式以外に変更したい場合は、{0}{1}{2}_{3}の部分を変更します。

例えばyyyy-mm-ddファイル名としたい場合は{0}-{1}-{2}{3}とします。

正規表現の詳しい仕様については、懇切丁寧に解説してくれているサイトがたくさんありますので割愛致します。

また、$Matches変数も何がどういう順番で格納されるのか、実際に変数の中身を表示させながら実行してみてください。

yyyymmdd_をyyyy-mm-ddに変更する

先ほどとは逆にyyyymmdd_をyyyy-mm-ddに変更するときは正規表現の部分を少し変更すれば可能です。

Get-ChildItem -Recurse |Where-Object{$_ -match '^((\d{4})(\d{2})(\d{2})_)(.*)'}|Rename-Item -NewName ('{0}-{1}-{2}_{3}' -f $Matches[2],$Matches[3],$Matches[4],$Matches[5])

終わりに

Rename-Itemコマンドレットについて紹介しました。

このコマンドレットを使うときは正規表現をセットで使えるとすごくエレガントなシェル芸ができると思います。

ぜひRename-Itemのパイプ処理と正規表現でファイルサーバー内をキレイにしてあげてください。

というわけで、ここまでお読みいただき、ありがとうございました。