雜記 › 技術筆記 › 序號位數只是下限、重名時 (2) 插在後綴之前:批次重新命名 2000 個檔案的實測口徑

序號位數只是下限、重名時 (2) 插在後綴之前:批次重新命名 2000 個檔案的實測口徑

跑完重新命名腳本才發現兩個檔案撞在一起;另一批照片的序號位數設成 3,腳本裡混著 6 個 8 字元的名字。這不是規則沒生效,而是規則跟表單上寫的約束不是一回事。

批次重新命名 範本裡那幾個函式抽出來跑一遍,落點很具體:位數只是下限,編號插在主名與後綴之間,手改過的那一行當下根本不跑避讓。

位數設的是下限,不是寬度

「序號位數」那欄寫著 min="0" max="9",看著像被約束住了,真正執行的只有 brPad(T300 起):位數不夠時補 0,從來不裁。brPad(999,3) 得 999,brPad(10000,3) 得 10000。那兩個表單屬性對 JS 沒有約束力,pad=9 得 000000001.jpg,填 12 得 000000000001.jpg,填 -2 也照程式碼生效。

規模 / 位數字元數分佈讀法
105 個 / pad=26 字元 99 個,7 字元 6 個第 100 個起整列變寬
1005 個 / pad=37 字元 999 個,8 字元 6 個999 之後只能多一位
12 個 / pad=1216 字元 12 個表單的 max=9 不被執行
1005 個檔案 pad=3 7 字元 999 8 字元 6 圖 1:位數只補零不截斷

重名:編號插在後綴之前

conflict 的預設檔 auto 遇到一堆行指向同一個名字時,不報錯、不跳過、也不覆蓋先到的那一行,而是把後撞的改成「主名 + 空格 + (2) + 原樣的點和後綴」,行內標「重名,已自動追加編號」。50 行全撞時末行是 same.txt (50).txt,帶標註的只有 49 行。編號落在主名與原後綴之間:a.b.tar.gz 撞車後追加出來的是 x.tar.gz (2).gz。

判撞名用 toLowerCase,Photo.jpg / PHOTO.JPG / photo.jpg 算同一個坑,避讓後寫成 same.txt (2).JPG——編號加上了,後綴大小寫仍跟著各行原樣;另一檔 skip 寫「重名,已保持原名」。

手改與關掉的那一行:避讓的兩個例外

行內改名字走 brEditRow(T561-571),只重算統計條和腳本,不跑 brDedupe。把 p.txt 與 q.txt 兩行都手打成 p.txt,表格當場兩條同名,匯出也兩條都收,腳本裡那條 Rename-Item -LiteralPath 'q.txt' -NewName 'p.txt' 改的是磁碟上已經存在的名字。要等下一次規則變化,brDedupe 才把它補成 p (2).txt。

關掉某一行的「改名」,它不再產新名,卻照樣先佔住原名:x.txt 與 b.txt 兩行,find 寫 x、repl 寫 b,再把 b.txt 那行關掉,活著的 x.txt 會被推成 b (2).txt。這一頁 0 次磁碟寫回,沒有 undo、redo、history,改名全靠匯出的 ps1 / bat / sh。

後綴的四條口徑

brSplitName 只認最後一個點,a.tar.gz 的主名是 a.tar、後綴是 gz;.gitignore 這類點開頭的名字判成「無副檔名」,前導點保留。大小寫不越界:選「全部小寫」時 DSC Photo JPG.jpeg 出來是 dsc-photo-jpg.jpeg,尾巴上的 .jpeg 一動不動,後綴要小寫必須另外選「統一小寫」。

沒勾「連副檔名一起取代」時,取代只餵最後一個點之前的主名:find 寫 \..*、repl 留空,a.tar.gz 只得到 a.gz,因為程式又把原後綴接回末尾;find 寫成字面的 .gz 時輸出完全不變,勾上開關才得到 a。反向的坑是副檔名選「強制指定」卻不填值,Photo.JPG、doc.pdf 變成 Photo、doc,後綴整段消失,還不進「規則有問題」統計。

取代串裡的 $ 不是字面量

勾上「按正則處理」後,repl 那欄的 $ 走 JS 取代語義。find 寫 b、repl 寫 $`X,abc.jpg 變成 aaXc.jpg:匹配之前那段 a 被整塊塞進取代串;寫 $&$& 得 abbc.jpg,寫 $9 而沒有第 9 組時原樣留 a$9c.jpg。字面模式裡按字面處理。

正則寫錯不會把頁面弄崩:brReplace 回傳一個哨兵串(T395),行內提示「正則運算式寫錯了」並保留原名,代價是判壞的整列不進匯出。3 個檔案、find 寫 (:3 行都留在原名並標紅,統計條「規則有問題:3」,匯出 0 行、腳本框是空的,打包只彈「沒有可匯出的檔案」。

上限和另外幾個硬頂

一次最多收 2000 個。拖 2005 個進去,files 記 2000、表格 2000 行,預覽只畫前 400 行,末尾補一句「另有 1600 行未在預覽裡顯示」。Rename-Item、ren、mv -n 各 2000 條,匯出也是 2000 行。

拖入 2005 個之後 預覽行 400 匯出行 2000 腳本行 2000 圖 2:預覽之外仍算全量

另外三個數字也管著名字落地。主名的 160 字元硬頂:204 字元的原名截到 160 再接回 .txt,最終整名 164 字元,行內寫「名稱過長,已截到 160 字元」。Windows 保留名共 22 項(CON、PRN、AUX、NUL 加 COM 與 LPT 各 1 到 9),命中時加底線前綴,CONSOLE.txt 和 LPT10 不判定。非法字元勾了清理是刪掉,取消勾選換成底線,note 仍寫「已去掉非法字元」。

三個當場被問到的

Q:位數設小了,長名字會不會被截斷?

不會。brPad 只在不夠長時補 0,1005 個檔案配 pad=3 依然留下 6 個 8 字元的名字;真正會截的是主名那條 160 字元硬頂。

Q:手改過一行之後,重名還會自動避讓嗎?

當下不會。brEditRow 不跑 brDedupe,兩條同名可以一起進匯出,要等下一次規則變化才被補成 p (2).txt。點任意範本按鈕還會走 T679-683 那條無條件賦值,把手改過的行一起重算掉,沒有還原入口。

Q:匯出的批次處理遇到同名會自己停下來嗎?

腳本頭部寫著「重名會報錯並停下」,但產生的 .bat 實測只有 @echo off、chcp 65001 >nul、rem 頭加逐條 ren 共 13 行,沒有 errorlevel、if exist、exit 任何一句,ren 撞名只印一行錯誤、後面的命令接著跑。帶「已有同名就不覆蓋」語義的是 sh 的 mv -n;更通用的引號與中斷口徑,批次建目錄那篇已經踩過一遍。

匯出去跑之前看一遍

  • 把目標名那一列排一次序找重複,手改過的行沒參與避讓。
  • 看序號那一列的字元數分佈,pad=3 裡混進 8 字元是進位,不是設定丟了。
  • 副檔名選「強制指定」就必須填值,留空等於整段刪掉後綴。
  • 勾了正則就把「規則有問題」讀到 0 為止,壞的那幾行不進匯出;取代串裡 $ 打頭的寫法先用正則測試對一遍結果。

📎 相關文章

70 個位元組沒動,MIME 類型換了 13 次:副檔名才是唯一輸入 2026-10-23 轉 JPG 時透明被強制填底色:91 個品質檔位在 PNG 面前不參與編碼 2026-10-23 「全部清除」後還剩 553 位元組,「只去掉位置信息」連縮圖都沒動 2026-10-23 兩條憑證指紋一條 95 個字元一條 64 個:差的 31 個全是冒號,摘要物件是整張 DER 2026-10-23 TOTP 口令差 30 秒就換碼:±1 期反查只倒推方向,演算法也只過 SHA-1 一檔 2026-10-23