パイプされたファイル/フォルダに連番を振るコマンドレットです。以前の記事 同様に -execute
オプション指定時のみリネームを実行するようにして誤操作に対する安全性を高めています。
環境
Name Value
---- -----
PSVersion 7.0.3
PSEdition Core
GitCommitId 7.0.3
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
動作イメージ
先頭に追加
先頭に追加 & ファイル名統一
末尾に追加
末尾に追加 & ファイル名統一
その他オプション
ほかにもパラメータで以下を指定できます。
- 連番をいくつから開始するか
- いくつおきに連番を振るか
- 連番を何桁でゼロ埋めするか
コード
function Rename-Index {
<#
.SYNOPSIS
連番リネーム
.DESCRIPTION
パイプライン経由での入力にのみ対応(出力なし)
.PARAMETER basename
拡張子を覗いた部分のファイル/フォルダ名
.PARAMETER start
連番の開始番号
.PARAMETER pad
インデックスの桁数
.PARAMETER execute
指定した場合のみリネーム
.PARAMETER step
連番の増分
.PARAMETER tail
指定時はファイル名末尾に挿入
.EXAMPLE
ls * | Rename-Index
#>
param (
[string]$basename,
[int]$start = 1,
[int]$pad = 2,
[int]$step = 1,
[switch]$tail,
[switch]$execute
)
$proc = $input | Where-Object {$_.GetType().Name -in @("FileInfo", "DirectoryInfo")}
$shiftJIS = [System.Text.Encoding]::GetEncoding("Shift_JIS")
if ($basename) {
$longestName = $proc.Name | Sort-Object {$shiftJIS.GetByteCount($_)} -Descending | Select-Object -First 1
$fill = $shiftJIS.GetByteCount($longestName) + 1
}
$ANSI_BlackOnGreen = "`e[42m`e[30m"
$ANSI_BlackOnWhite = "`e[47m`e[30m"
$ANSI_Reset = "`e[0m"
$bgColor = ($execute)? $ANSI_BlackOnGreen : $ANSI_BlackOnWhite
$start -= $step
$proc | ForEach-Object {
$start += $step
$index = "{0:d$($pad)}" -f $start
$fileName = $_.Name
if ($basename) {
Write-Host $fileName -ForegroundColor DarkGray -NoNewline
$leftIndent = $shiftJIS.GetByteCount($fileName)
" {0}=> " -f ("=" * ($fill - $leftIndent)) | Write-Host -NoNewline
$nameParts = ($tail)?
@($basename, $index, $_.Extension):
@("", $index, ($basename + $_.Extension))
}
else {
$nameParts = ($tail)?
@($_.Basename, "_$($index)", $_.Extension):
@("", "$($index)_", $fileName)
}
"{0}$($bgColor){1}$($ANSI_Reset){2}" -f $nameParts | Write-Host
if (-not $execute) {
return
}
$renamedName = $nameParts -join ""
try {
$_ | Rename-Item -NewName $renamedName -ErrorAction Stop
}
catch {
Write-Host ("ERROR: failed to rename '{0}' to '{1}'!" -f $fileName, $renamedName) -ForegroundColor Magenta
(Test-Path $renamedName)?
"(same name exists in directory)":
"(other process may opening file)" | Write-Host -ForegroundColor Magenta
}
}
}
PowerShell 7 で三項演算子とエスケープシークエンス ``e` が導入されてかなり短く記述できるようになりました。