PowerShellでカジュアルにファイル名を置換したい。
PowerShellでファイル名置換するときの決まり文句
以下エイリアス(alias)をつかっているだけで、すべて同じ意味の構文になる。
Get-ChildItem | Rename-Item -NewName { $_.Name -replace '置換対象文字列','置換後文字列'}
gci | ren -NewName { $_.Name -replace '置換対象文字列','置換後文字列'}
ls | rni -NewName { $_.Name -replace '置換対象文字列','置換後文字列'}
上記で重要なのは、get-childitemで取得したファイルを | パイプラインでわたしていること。
$_.Nameはパイプラインからわたってきたファイル名が格納されているのがポイント。
replaceだけではファイル名を変更できない
たとえば以下のようにreplaceだけでは置換されてもファイル名は変更されない
$name = gci *.txt
$name.replace("置換対象文字列", "置換後文字列")
write-host $name #置換はされるが、ファイル名は変更されない
PowerShellでカジュアルに置換する
$name = gci *.txt
$name | ren -newname { $_.name -replace '置換対象文字列','置換後文字列'}
カジュアルといってもただ変数使っただけだけど・・・。
move-itemでもファイル名を変更できるけど、置換はなにかと便利かもしれない。Qiitaにもあるように、置換対象文字列で正規表現もつかえたりで結構すごい。
やりたいこととなんかちょっと違うけどまあいいか・・・。
ここからはファイル名置換に関連する知っておいたほうが良い情報を書きます。
PowerShellでデータ型を確認する
echo "hoge".gettype().fullname
# System.String
$filelist = ls *.jpg
foreach($f in $filelist){echo $f.gettype().fullname}
# System.IO.FileInfo
PowerShellで型変換する
$filelist = ls *.jpg
foreach($f in $filelist){
$f = [string]$f
echo $f.gettype().fullname
}
# System.String
PowerShellでファイル名を取得する
拡張子を含むファイル名を取得する
$filelist = ls .jpg
foreach($f in $filelist){[System.IO.Path]::GetFileName($f)}
# xxx.jpg
拡張子なしのファイル名を取得する
$filelist = ls *.jpg
foreach($f in $filelist){[System.IO.Path]::GetFileNameWithoutExtension($f)}
# file01
拡張子だけ取得
$filelist = ls *.jpg
foreach($f in $filelist){[System.IO.Path]::GetExtension($f)}
# .jpg
パスから親の要素を取得
$filelist = ls *.jpg
foreach($f in $filelist){Split-Path -Parent $f}
# C:/users/xxxxxx/desktop
パスから末尾の要素を取得
$filelist = ls *.jpg
foreach($f in $filelist){Split-Path -Leaf $f}
ほかSplit-Pathのオプション
- -Qualifier → ルートディレクトリを取得
- -NoQualifier → ドライブ文字以外を取得
そのほかパスを統合するjoin-pathやパスをチェックするtest-pathコマントレットもあります。
置換ではなく通常通りリネームする方法
$filelist = ls *.jpg
$count = 0
foreach($f in $filelist){$count += 1; ren $f "xxx$count.jpg"}

コメント