我有一个文件夹结构:
/mnt/data/mydata/mydata/several-files-and-folders-here
我希望它是:
/mnt/data/mydata/several-files-and-folders-here
我试过了mv
,但它抱怨该文件夹不是空的,而且我无法找到我理解的可行的快速解决方案,我对学习 Linux 还是个新手。如何正确解决这个问题?
我有一个文件夹结构:
/mnt/data/mydata/mydata/several-files-and-folders-here
我希望它是:
/mnt/data/mydata/several-files-and-folders-here
我试过了mv
,但它抱怨该文件夹不是空的,而且我无法找到我理解的可行的快速解决方案,我对学习 Linux 还是个新手。如何正确解决这个问题?
将子目录中的每个文件移动到父目录是一种方法,但如果 中有大量条目,
/mnt/data/mydata/mydata/
并且这是 中唯一的条目/mnt/data/mydata
,您可能会考虑这 3 个元数据操作序列,它不会更改大目录的内容目录,只是将它移动到文件系统中的不同位置。并从一个小目录中删除 1 个条目,然后取消链接。因此它不会影响子目录中任何文件的 ctime,甚至不必列出该大目录的内容。
原来的目录 inode
/mnt/data/mydata/mydata
现在是/mnt/data/mydata
,它的内容没有改变。如果它包含数百万个文件,那会更快并且需要更少的 i/o。但更多的是打字,因为mv
不会为您发明一个临时名称。如果原来的
/mnt/data/mydata
不是空的,你仍然可以这样做,但不是rmdir
,mv /mnt/data/mydata.old/* /mnt/data/mydata/
。如果它有几个条目,而子目录有几百万个条目,那就可以节省一些 I/O。您确实需要对 的写入权限
/mnt/data
,而另一种方式则不需要。但这不需要对/mnt/data/mydata/mydata
.根据您的喜好编写脚本,和/或
cd
使用相对路径。选择您想要的任何临时名称,例如foo
ortmp
或xyz123
。(如果其他用户可以编写/mnt/data
,而您正在编写脚本,请检查mv
如果他们创建一个具有您选择的相同随机名称的文件会做什么;或者在您取消链接时mktemp -p /mnt/data/
使用那里获取临时目录以将孩子移动到其中。)mydata
/mnt/data/mydata
它的缺点是操作之间有一个
/mnt/data/mydata
根本不存在的时刻。除非有用于系统renameat2
调用的RENAME_EXCHANGE
shell 包装器以原子方式交换两条路径。(Linux 内核 3.15,glibc 2.28,所以它已经存在了一段时间,但rename(1)
没有mv(1)
使用它的选项。)如果您正在运行服务器,这可能对您很重要,否则您可能不在乎。
交互式地,您还可以使用
imv /mnt/data/mydata
readline 行编辑来交互式地编辑路径(与 bash 用于命令行编辑的方式相同。)它是如何完成的
它的完成方式是您需要移动以下内容:
到
首先......然后你可以删除现在空的目录,如果你愿意,例如:
rmdir
是安全的......它只会删除目录,如果它是空的,否则会出错。如何移动
要么(没有试运行)简单地:
注意:
echo
beforemv
只是防止意外复制/粘贴的安全措施......你需要删除它才能使命令工作......这里没有空运行,所以要小心。或者(通过空运行)利用围绕重复目录名称之一的 shell 参数扩展(
bash
例如,前导目录名称为:"${parameter/mydata\//}"
或尾随目录名称为"${parameter%mydata/*}${parameter##*/}"
:)和for
循环......单行将是这样的简单如:注意:在安全试运行
echo
之前插入...只有在对输出满意时才删除,然后再次运行命令以进行实际移动。mv
echo
示范: