如何创建编号备份?

如何创建编号备份?

一些 GNU 实用程序(例如mvcp)可以创建编号备份(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论点可能也需要引号。
  • 我执行&&这些命令是为了避免在失败时收到错误消息等等mvmktemp
  • --如果文件名以破折号开头,则添加选项/参数分隔符。
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 exitwhat 会阻止 perl 打印匹配计数,否则会污染名称。

您可能还想将其添加2>/dev/null到行尾,以便在文件不存在时保持安静。

相关内容