でも、人間管理むりっぽだよ。
いくらパソコンつかえてもさ…
というわけで、ITエンジニアらしく、検索ツールを作ったんだ
# Show-NextEID.ps1
# cd "C:\Users\OneDrive\ドキュメント\Private\創作\とある天才の物語\03_STORY(エピソード台帳・台本)"
#
## ファイル名から最新EID→次候補を表示
# powershell -ExecutionPolicy Bypass -File .\Show-NextEID.ps1
#
## state/ledgerも併せて表示(ズレ検出に便利)
# powershell -ExecutionPolicy Bypass -File .\Show-NextEID.ps1 -CheckState -CheckLedger
param(
[string]$Root = (Get-Location).Path,
[int]$NextCount = 5,
[switch]$IncludeOutline,
[switch]$CheckState,
[switch]$CheckLedger
)
$ErrorActionPreference = "Stop"
function ToInt36([string]$s){
$s = $s.ToUpperInvariant()
if($s.Length -ne 3){ throw "EID must be 3 chars: $s" }
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$val = 0
foreach($ch in $s.ToCharArray()){
$idx = $chars.IndexOf($ch)
if($idx -lt 0){ throw "invalid base36 char: $ch in $s" }
$val = ($val * 36) + $idx
}
return $val
}
function ToBase36_3([int]$n){
if($n -lt 0){ throw "n must be >= 0" }
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$s = ""
do {
$s = $chars[$n % 36] + $s
$n = [Math]::Floor($n / 36)
} while($n -gt 0)
return $s.PadLeft(3, "0")
}
$rootPath = [IO.Path]::GetFullPath($Root)
# collect txt
$files = Get-ChildItem -Path $rootPath -Recurse -File -Filter *.txt
if(-not $IncludeOutline){
$files = $files | Where-Object {
$rel = $_.FullName.Substring($rootPath.Length).TrimStart("\")
-not $rel.StartsWith("00_", [StringComparison]::OrdinalIgnoreCase)
}
}
# patterns
$reReal = [regex]'^C\d{2}_P\d{2}_T\d{4}_I\d{2}__([0-9A-Z]{3})__'
$rePh = [regex]'__EID___'
$maxInt = -1
$maxEid = ""
$maxFile = $null
$realCount = 0
$phCount = 0
foreach($f in $files){
$name = $f.Name
if($rePh.IsMatch($name)){
$phCount++
}
$m = $reReal.Match($name)
#Write-Host ("m: " + $m.Success + $m + " name: " + $name)
if($m.Success){
$realCount++
$eid = $m.Groups[1].Value.ToUpperInvariant()
$i = ToInt36 $eid
if($i -gt $maxInt){
$maxInt = $i
$maxEid = $eid
$maxFile = $f.FullName
}
}
}
Write-Host "---- EID Scan Result (from filenames) ----"
Write-Host ("Root: " + $rootPath)
Write-Host ("Files scanned: " + $files.Count)
Write-Host ("Files with real EID (__XXX__): " + $realCount)
Write-Host ("Files with placeholder (__EID___): " + $phCount)
if($maxInt -lt 0){
Write-Host "Max EID: (none found)"
Write-Host ("Next candidates: " + (0..([Math]::Max(0,$NextCount-1)) | ForEach-Object { ToBase36_3 $_ } -join ", "))
} else {
Write-Host ("Max EID: " + $maxEid + " (base36) => " + $maxInt + " (decimal)")
Write-Host ("Example file: " + $maxFile)
$nextStart = $maxInt + 1
$maxCap = 36*36*36 - 1 # ZZZ = 46655
if($nextStart -gt $maxCap){
Write-Host "WARNING: max EID reached (ZZZ). Next would overflow."
} else {
$cands = @()
for($k=0; $k -lt $NextCount; $k++){
$v = $nextStart + $k
if($v -gt $maxCap){ break }
$cands += (ToBase36_3 $v)
}
Write-Host ("Next candidates: " + ($cands -join ", "))
}
}
# Optional: check eid_state.json
if($CheckState){
$statePath = Join-Path $rootPath "eid_state.json"
Write-Host ""
Write-Host "---- Check: eid_state.json ----"
if(Test-Path -LiteralPath $statePath){
try {
$state = Get-Content -Raw -Encoding UTF8 -LiteralPath $statePath | ConvertFrom-Json
$next = [int]$state.next
Write-Host ("eid_state.json next: " + $next + " => " + (ToBase36_3 $next))
$usedCount = 0
if($state.used){ $usedCount = @($state.used).Count }
Write-Host ("eid_state.json used count: " + $usedCount)
} catch {
Write-Host ("Could not parse eid_state.json: " + $_.Exception.Message)
}
} else {
Write-Host "eid_state.json not found."
}
}
# Optional: check eid_ledger.csv
if($CheckLedger){
$ledgerPath = Join-Path $rootPath "eid_ledger.csv"
Write-Host ""
Write-Host "---- Check: eid_ledger.csv ----"
if(Test-Path -LiteralPath $ledgerPath){
try {
$rows = Import-Csv -Encoding UTF8 -LiteralPath $ledgerPath
$eids = $rows | ForEach-Object { $_.EID } | Where-Object { $_ -match '^[0-9A-Z]{3}$' }
$uniq = $eids | Select-Object -Unique
Write-Host ("eid_ledger rows: " + $rows.Count)
Write-Host ("eid_ledger unique EIDs: " + $uniq.Count)
if($uniq.Count -gt 0){
$maxL = ($uniq | ForEach-Object { [pscustomobject]@{E=$_; I=(ToInt36 $_)} } | Sort-Object I | Select-Object -Last 1)
Write-Host ("eid_ledger max EID: " + $maxL.E + " => " + $maxL.I)
$nextL = $maxL.I + 1
if($nextL -le (36*36*36 - 1)){
Write-Host ("eid_ledger next candidate: " + (ToBase36_3 $nextL))
}
}
} catch {
Write-Host ("Could not read eid_ledger.csv: " + $_.Exception.Message)
}
} else {
Write-Host "eid_ledger.csv not found."
}
}