需將目錄結構 10.11/xxx.jpg → 10.11/1011.jpg (目錄名去點當檔名)。本文展示 Shell 參數展開 ${var%%.*}、${var##*.}、find -execdir、rename (Perl) 多種批次重命名技巧。
10.11/
a.jpg
b.jpg
10.12/
c.jpg
# 目標:每個子目錄下的 *.jpg 重命名為「目錄名去點」.jpg
# 10.11/a.jpg → 10.11/1011.jpg
#!/bin/bash
for dir in */; do
[[ -d "$dir" ]] || continue
dirname="${dir%/}" # 移除尾部斜線
newname="${dirname//./}" # 移除所有點: 10.11 → 1011
# 或僅取第一段: newname="${dirname%%.*}${dirname##*.}"
cd "$dir"
for f in *.jpg; do
[[ -e "$f" ]] || continue
mv -- "$f" "${newname}.jpg"
done
cd ..
done
find . -mindepth 2 -maxdepth 2 -type f -name '*.jpg' -execdir bash -c '
dir="${PWD##*/}" # 取得當前目錄名
new="${dir//./}" # 移除點
for f; do
mv -- "$f" "${new}.jpg"
done
' _ {} +
# 先 cd 到包含子目錄的父目錄
rename -n 's{([^/]+)/.*\.jpg$}{$1}s/.\//g' */*.jpg
# -n 僅預覽,確認無誤後移除 -n
mmv '*/*.jpg' '#1#2.jpg'
# 需配合 sed 處理目錄名: mmv 不支援字串替換,通常搭配 shell 迴圈
| 語法 | 意義 | 範例 (var="10.11.jpg") |
|---|---|---|
${var%.*} | 移除最短尾部匹配 | 10.11 |
${var%%.*} | 移除最長尾部匹配 | 10 |
${var#*.} | 移除最短首部匹配 | 11.jpg |
${var##*.} | 移除最長首部匹配 | jpg |
${var//./} | 全域替換移除點 | 1011jpg |
# 遞迴所有子目錄,檔名 = 相對路徑替換 / 為 _
find . -type f -name '*.jpg' | while IFS= read -r f; do
rel="${f#./}"
new="${rel//\//_}"
mv -- "$f" "$new"
done
echo mv 或 rename -n 預覽。set -euo pipefail 並在腳本開頭 cp -r src dst_backup 備份。"$f" 並用 -- 結束選項。善用 Shell 參數展開與 find -execdir,複雜的批次重命名也能一行指令搞定。