所有照片擴展名為大寫 .JPG,上傳系統僅識別小寫 .jpg,需批量重命名。
主體.新擴展名#!/bin/bash
oldext="JPG"
newext="jpg"
dir=$(pwd)
for file in $(ls $dir | grep "\.$oldext$"); do
name=$(basename "$file" .$oldext)
mv "$file" "${name}.${newext}"
done
echo "change JPG ====> jpg done!"
關鍵命令解析:
ls $dir | grep "\.$oldext$":精確匹配以舊擴展名結尾的文件basename "$file" .$oldext:安全提取文件名主體(處理路徑、特殊字符)mv "$file" "${name}.${newext}":雙引號防止空格/特殊字符導致參數分割#!/bin/bash
read -p "Old extension: " oldext
read -p "New extension: " newext
read -p "Directory: " dir
cd "$dir" || { echo "Directory not found"; exit 1; }
for file in *."$oldext"; do
[ -e "$file" ] || continue # 無匹配文件時跳過
name=$(basename "$file" .$oldext)
mv "$file" "${name}.${newext}"
echo "$name.$oldext ====> $name.$newext"
done
echo "All files have been modified."
改進點:
read -p 交互式輸入cd "$dir" || exit 失敗即退出for file in *."$oldext":Shell 原生通配,避免 ls | grep 邊界問題[ -e "$file" ]:處理無匹配文件情況#!/bin/sh
# rename_suffix.sh
echo "Input suffix to replace: "
read SUFFIX_SRC
echo "Input new suffix: "
read SUFFIX_DST
for i in *.$SUFFIX_SRC; do
if [ -e "$i" ]; then
# basename 移除擴展名:basename file .ext
newname=$(basename "$i" .$SUFFIX_SRC).$SUFFIX_DST
echo "mv $i to $newname"
mv "$i" "$newname"
else
echo "File does not exist."
exit -1
fi
done
| 場景 | 解決方案 |
|---|---|
| 文件名包含空格/特殊字符 | 雙引號包裹變量,for f in *; do 而非 ls |
| 遞歸處理子目錄 | find . -name "*.JPG" -execdir bash -c 'mv "$1" "${1%.JPG}.jpg"' _ {} \; |
| 大小寫不敏感文件系統 | shopt -s nocaseglob 或 find -iname |
| 預覽不執行 | 先 echo mv ... 確認,去掉 echo 執行 |
| 撤銷操作 | 重命名前備份:cp -r dir dir.bak |
cat > rename_ext.sh << 'EOF'
#!/bin/bash
set -euo pipefail
read -rp "Old extension (without dot): " old
read -rp "New extension (without dot): " new
read -rp "Target directory: " target
cd "$target" || exit 1
for f in *."$old"; do
[ -e "$f" ] || continue
mv -v "$f" "${f%.$old}.$new"
done
EOF
chmod +x rename_ext.sh
掌握 Shell 參數展開(${var%pattern}、${var#pattern})、通配符與引用規則,能輕鬆應對各類批量文件處理需求。