You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Linux Shell脚本递归替换文件名中数字间的点为连字符

解决递归替换文件名中数字间点为连字符的问题

原脚本的问题

你之前的脚本存在两个核心问题:

  1. for file in *.* 仅能匹配当前目录下包含点的文件,无法递归处理子目录,还会漏掉不含点的文件名
  2. ${file//\d\.\d,\d\-\d} 是错误的替换语法:bash的参数扩展仅支持通配符匹配,不支持\d这类正则元字符,且替换格式完全不符合规则

正确的bash脚本

下面的脚本会递归遍历指定目录(或当前目录),仅将数字与数字之间的点替换为连字符,保留文件名中其他位置的点(比如Mr.里的点、后缀名的点):

#!/bin/bash

# 优先使用传入的目录参数,无参数则用当前目录
TARGET_DIR="${1:-.}"

# 递归查找所有文件,避免处理目录
find "$TARGET_DIR" -type f | while IFS= read -r full_path; do
    # 拆分文件目录和文件名
    file_dir=$(dirname "$full_path")
    old_name=$(basename "$full_path")
    
    # 用sed替换所有数字间的点:捕获前后数字,将中间的点换成连字符
    new_name=$(echo "$old_name" | sed -E 's/([0-9])\.([0-9])/\1-\2/g')
    
    # 仅当文件名有变化时执行重命名,避免无效操作
    if [ "$old_name" != "$new_name" ]; then
        # 加上-v参数可以显示重命名过程,方便验证
        mv -v "$full_path" "$file_dir/$new_name"
    fi
done

read -n 1 -p "Hit any key to exit"

脚本说明

  1. 递归处理:用find命令遍历目标目录下所有文件,包括子目录中的文件
  2. 文件名安全处理:IFS= read -r full_path确保能正确处理包含空格、特殊字符的文件名
  3. 精准替换:sed -E 's/([0-9])\.([0-9])/\1-\2/g'使用扩展正则表达式,仅匹配数字.数字的组合,将中间的点替换为连字符,全局替换保证处理多个连续的数字点(比如1.1.4→1-1-4)
  4. 安全校验:只有当新旧文件名不同时才执行重命名,避免不必要的操作

使用方法

  1. 将脚本保存为fix_filenames.sh
  2. 赋予执行权限:chmod +x fix_filenames.sh
  3. 运行脚本:
    • 处理当前目录:./fix_filenames.sh
    • 处理指定目录:./fix_filenames.sh /path/to/your/media/folder

测试建议

在实际执行重命名前,可以先将mv -v改成echo mv -v,这样脚本只会输出将要执行的重命名操作,不会实际修改文件名,确认无误后再改回mv -v执行。

特殊需求调整

如果需要仅替换文件名开头的连续数字段中的点(比如你的示例中3.4不想替换),可以将sed命令修改为:

new_name=$(echo "$old_name" | sed -E 's/^([0-9]+)\.([0-9]+)/\1-\2/g; s/(-[0-9]+)\.([0-9]+)/\1-\2/g')

这个正则会仅处理开头的数字-点序列,比如1.2 3.4 foo.bar会变成1-2 3.4 foo.bar,符合你给出的示例期望。

内容的提问来源于stack exchange,提问作者Chris Fox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 01:15:02