我曾经这样做过榛。我会根据文件扩展名将所有内容从 移动到~/Downloads/
、~/Downloads/Archive/Pictures
等~/Downloads/Archive/Documents
,~/Downloads/Archive/Videos
当已经存在同名文件时,Hazel 只会在移动的文件后附加一个数字。
我想编写一个可以实现此目的的 shell 脚本,但我很快意识到我不知道如何在没有任何用户输入的情况下重命名文件。重命名的方案可以是文件名后的一个简单的计数器,它应该只在mv
否则会覆盖现有文件时发生。如果已经存在许多具有相同文件名的实例,它还应该能够继续计数。因此,如果我要移动dirA/file.ext
到dirB/
已经存在file.ext
和的文件file2.ext
,脚本应该从 3 开始计数并重命名dirA/file.ext
为dirB/file3.ext
。
有人能提供一些关于如何实现这一点的指导吗?最好使用 shell 脚本,但如果没有,那么可以使用 Ruby、Perl 或 Python。只要知道使用 shell 脚本是否可行,就会对我有所帮助。
答案1
没那么难。如果目标文件存在,你只需要将文件拆分为基本名称和扩展名,并增加一个计数器,直到目标目录中不存在新文件名。
source=dirA/file.ext
dest_dir=dirB
file=$(basename file.ext)
basename=${file%.*}
ext=${file##*.}
if [[ ! -e "$dest_dir/$basename.$ext" ]]; then
# file does not exist in the destination directory
mv "$source" "$dest_dir"
else
num=2
while [[ -e "$dest_dir/$basename$num.$ext" ]]; do
(( num++ ))
done
mv "$source" "$dest_dir/$basename$num.$ext"
fi
答案2
如果每个工作站都安装了 GNU 版本,您也可以使用单个命令执行此操作mv
。Mac OS X 附带的默认版本不支持此--backup
开关。您可以通过 Macports 和许多其他位置获取适用于 Mac OS X 的 GNU Coreutils。
那么问题就只是:
mv --backup=编号 dirA/文件.ext dirB/
生成的文件名将是file.ext.~1~
,file.ext.~2~
等等。
答案3
感谢 glenn,我重写了该功能,使其支持空扩展名,并接受直接文件作为目标(就像平常一样mv
)
mv_no_override() {
local dir file ext base num
if [ -d "$2" ]; then
dir=$2
file=$(basename "$1")
else
dir=$(dirname "$2")
file=$(basename "$2")
fi
ext="$(sed -r 's/.+(\..+)|.*/\1/' <<<"$file")"
base="$(sed -r 's/(.+)\..+|(.*)/\1\2/' <<<"$file")"
while [ -e "$dir/$base$num$ext" ]; do
(( num++ ))
done
mv "$1" "$dir/$base$num$ext"
}