以bash方式移动文件并自动重命名复制文件而不覆盖现有文件的方法

时间:2011-12-28 13:27:08

标签: macos bash unix scripting file-rename

我正在用大量的jpgs对大量目录进行一些重大的重组,其中一些与其他目录中的文件同名。我想将文件移动/复制到备用目录,并且如果名称与该目录中的另一个文件匹配(将IMG_238.jpg重命名为IMG_238_COPY1.jpgIMG_238_COPY2.jpg等),则bash会自动重命名它们,而不是覆盖现有文件。

我已经设置了一个脚本,它接受jpeg并根据exif数据将它们移动到一个新目录。移动一个jpg的脚本的最后一行是:mv -n "$JPEGFILE" "$DIRNAME"

我正在使用-n选项,因为我不想覆盖文件,但现在我必须手动排序那些没有被移动/复制的文件。我的GUI自动执行此操作...在bash中有相对简单的方法吗?

(如果重要的话,我在Mac OSX Lion中使用bash 3.2。)

2 个答案:

答案 0 :(得分:4)

这应该这样做

# strip path, if any
fname="${JPEGFILE##*/}"
[ -f "$DIRNAME/$fname" ] && {
    n=1
    while [ -f "$DIRNAME/${fname%.*}_COPY${n}.${fname##*.}" ] ; do
        let n+=1
    done
    mv "$JPEGFILE" "$DIRNAME/${fname%.*}_COPY${n}.${fname##*.}"
} || mv "$JPEGFILE" "$DIRNAME"

编辑:改进。

答案 1 :(得分:2)

您可以尝试downloading并查看Ubuntu / Debian的基于Perl的rename是否有效。它具有sed样式功能。手册页(在我的系统上,但脚本应该与链接的相同):

  

“rename”重命名根据指定规则提供的文件名      作为第一个论点。 perlexpr参数是Perl表达式      预计至少会有一些修改Perl中的$ _字符串      指定的文件名。如果给定的文件名未被修改      表达式,它不会被重命名。如果没有给出文件名      命令行,文件名将通过标准输入读取。

     

例如,重命名匹配“* .bak”的所有文件以删除     扩展,你可能会说

    rename 's/\.bak$//' *.bak
     

要将大写名称翻译为较低的名称,请使用

    rename 'y/A-Z/a-z/' *