我有一个文件夹结构:
/mnt/data/mydata/mydata/several-files-and-folders-here
我希望它是:
/mnt/data/mydata/several-files-and-folders-here
我尝试过,mv但它抱怨文件夹不为空,并且我无法找到我理解的可行的快速解决方案,我对学习 Linux 仍然是新手。如何正确解决这个问题?
Pet*_*des 11
将子目录中的每个文件移动到父目录中是一种方法,但如果 中存在大量条目/mnt/data/mydata/mydata/,并且这是 中的唯一条目/mnt/data/mydata,您可能会考虑这 3 个元数据操作的序列,这些操作不会更改大目录的内容目录,只需将其移动到文件系统中的不同位置。并从小目录中删除 1 个条目,然后取消链接。
因此,它不会影响子目录中任何文件的 ctime,甚至不必列出该大目录的内容。
mv /mnt/data/mydata /mnt/data/mydata.old # rename parent
mv /mnt/data/mydata.old/mydata /mnt/data/mydata # subdir -> sibling of parent
rmdir /mnt/data/mydata.old # fails if not empty
Run Code Online (Sandbox Code Playgroud)
原来的目录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或tmp、 或xyz123。(如果其他用户可以编写/mnt/data,并且您正在编写脚本,请检查mv如果他们创建一个与您选择的随机名称相同的文件会做什么;或者使用mktemp -p /mnt/data/在那里获取一个临时目录,以便mydata在您取消链接时将子项移动到其中/mnt/data/mydata。)
它的缺点是操作之间有一个/mnt/data/mydata根本不存在的时刻。除非有一个用于系统renameat2调用的RENAME_EXCHANGEshell 包装器来自动交换两个路径。(Linux 内核 3.15、glibc 2.28,所以它已经存在了一段时间,但rename(1)没有mv(1)使用它的选项。)
如果您正在运行服务器,这可能对您很重要,否则您可能不关心。
交互式地,您还可以使用imv /mnt/data/mydatareadline 行编辑来交互式地编辑路径(与 bash 用于命令行编辑的方式相同)。
完成的方式是您需要移动以下内容:
\n/mnt/data/mydata/mydata/\nRun Code Online (Sandbox Code Playgroud)\n到
\n/mnt/data/mydata/\nRun Code Online (Sandbox Code Playgroud)\n首先...后记,如果您愿意,您可以删除现在为空的目录,例如:
\nrmdir -v /mnt/data/mydata/mydata/\nRun Code Online (Sandbox Code Playgroud)\nrmdir是安全的...它只会删除该目录,如果它是空的,否则会出错。
要么(没有空运行)简单地:
\n/mnt/data/mydata/mydata/\nRun Code Online (Sandbox Code Playgroud)\n注意:echobeforemv只是防止意外复制/粘贴的安全措施...您需要将其删除才能使命令正常工作...这里没有空运行,所以要小心。
或者(通过 dry-run)利用bash\ 的shell 参数扩展围绕任一重复的目录名称(例如,前导目录带有:"${parameter/mydata\\//}"或尾随目录带有:"${parameter%mydata/*}${parameter##*/}")和for一个循环...单行将是某种东西就像这样简单:
/mnt/data/mydata/\nRun Code Online (Sandbox Code Playgroud)\n注意:echo之前插入是mv为了安全空运行...echo仅当对输出满意时才删除并再次运行命令以进行实际移动。
示范:
\nrmdir -v /mnt/data/mydata/mydata/\nRun Code Online (Sandbox Code Playgroud)\n