在可能发生名称冲突的情况下将文件和子目录“向上子目录”移动的便捷方法是什么?

在可能发生名称冲突的情况下将文件和子目录“向上子目录”移动的便捷方法是什么?

我的目录中有一些文件和目录/var/foo/bar/baz。现在,我想将它们全部移至/var/foo/bar,并摆脱 baz。容易,对吧?

cd /var/foo/bar
mv baz/* .
rmdir baz

(为了讨论的目的,我忽略了以 . 开头的文件)

但!如果baz/包含名为 的非目录文件怎么办baz?我可以将其移动到其他地方,或者使用临时文件名,然后删除该目录baz,然后将其移动到位。但这很乏味,而且命令也很多……还有另一种习惯的、更简单/更优雅的方法吗?

笔记:

  • 如果存在其他名称冲突,mv则覆盖(并且可能提示)的正常语义是可以的。但对于baz,它不会这样做,它只会失败。

答案1

cd /var/foo/bar/baz
for src in *; do
    dest="${src}"
    suffix=0
    while [[ -e ../"${dest}" ]]; do
        dest="${src}.${suffix}"
        suffix=$((suffix+1))
    done
    mv -n "$src" ../"$dest"
done
cd ..
rmdir baz

一个相当简单的解决方案。准备将文件从当前目录移动到父目录,但如果已存在具有该名称的文件,请添加带有数字的后缀。但请确保不要使用以下数字由于某种原因已经存在了。

如果任何被调用的东西存在,无论是目录、套接字、常规文件还是任何其他可能存在的东西, 该构造[[ -e file ]]将返回 true。file

答案2

这太长了,但应该可以:

cd /var/foo/bar
bazbaz_tmp_file=$(mktemp baz/XXXXXXXXXXXXXX)
[[ -e baz/baz ]] && mv baz/baz $bazbaz_tmp_file
mv baz/* .
rmdir baz
mv $(basename $bazbaz_tmp_file) baz

注意:这假设我们可以安全地将任何其他文件从baz/.

相关内容