一些 GNU 实用程序(例如mv
和cp
)可以创建编号备份(foo.~1~
)。其他(例如wget
)则不能。我想在运行默认覆盖文件的工具之前创建编号备份。以下bash
函数似乎可以满足我的需要:
backup(){ # back up the file, emacs style
file=$1
if test -f "${file}"; then
/bin/mv --backup=numbered "$(mktemp ${file}XXX)" "${file}"
/bin/rm "${file}"
fi
}
例如像这样使用:
backup foo
curl http://.... > foo
我想知道是否有更好的方法。
答案1
对 OP 的解决方案进行了小幅改进,使其更具普遍用途:
- 与目录一起使用。
- 这个
mktemp
论点可能也需要引号。 - 我执行
&&
这些命令是为了避免在失败时收到错误消息等等mv
。mktemp
--
如果文件名以破折号开头,则添加选项/参数分隔符。
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
顺便说一句,cp
支持使用源 == 目标进行编号备份。
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
答案2
仍然不是完全一行代码,但通过一次对 perl 的调用以及其强大的e
选项(即执行替换部分),你可以更接近它:
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
请注意,and exit
what 会阻止 perl 打印匹配计数,否则会污染名称。
您可能还想将其添加2>/dev/null
到行尾,以便在文件不存在时保持安静。