AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 24067
In Process
Thomas Vander Stichele
Thomas Vander Stichele
Asked: 2009-06-12 05:24:40 +0800 CST2009-06-12 05:24:40 +0800 CST 2009-06-12 05:24:40 +0800 CST

Unix上的递归移动实用程序?

  • 772

有时我有两棵树,它们曾经具有相同的内容,但已经不同步了(因为我移动了磁盘或其他原因)。一个很好的例子是我从 Fedora 镜像上游包的树。

我想通过将所有文件从 tree1 移动到 tree2 来再次合并这两棵树。

通常我这样做:

rsync -arv tree1/* tree2

然后删除tree1。

但是,这需要大量的时间和磁盘空间,而且这样做会容易得多:

mv -r tree1/* tree2

换句话说,递归移动。它会更快,因为首先它甚至不会复制,只需移动 inode,其次我不需要最后删除。

这存在吗?

作为测试用例,请考虑以下命令序列:

$ mkdir -p a/b
$ touch a/b/c1
$ rsync -arv a/ a2
sending incremental file list
created directory
./
b/
b/c1
b/c2

sent 173 bytes  received 57 bytes  460.00 bytes/sec
total size is 0  speedup is 0.00
$ touch a/b/c2

什么命令现在具有将 a/b/c2 移动到 a2/b/c2 然后删除 a 子树的效果(因为其中的所有内容都已经在目标树中)?

unix recursive
  • 11 11 个回答
  • 21676 Views

11 个回答

  • Voted
  1. Bill B
    2009-06-12T05:43:58+08:002009-06-12T05:43:58+08:00

    根据 gnu 的 mv(1) 联机帮助页mv:

    -u, --update move only when the SOURCE file is newer than the destination file or when the destination file is missing

    • 2
  2. Javier
    2009-06-12T10:02:05+08:002009-06-12T10:02:05+08:00

    建议mv -uf dir1/* dir2/移动(子)目录,而不是每个文件。你可以尝试使用find

    cd dir1
    find . -type d -exec mkdir -p dir2/"{}" \;
    find . -type f -exec mv -uf "{}" dir2/"{}" \;
    

    或类似的东西

    • 2
  3. David Spillett
    2009-06-12T05:44:04+08:002009-06-12T05:44:04+08:00

    才不是

    mv -uf tree1/* tree2/
    

    工作?

    • 1
  4. sunny256
    2009-06-12T05:52:19+08:002009-06-12T05:52:19+08:00

    午夜指挥官(mc)也很适合这种东西。使用 CTRL-t 标记文件,按 F6,当它要求覆盖目标文件时,如果要覆盖旧文件,请选择更新。

    • 1
  5. Bekir Dogan
    2012-08-31T18:11:06+08:002012-08-31T18:11:06+08:00

    您可以使用“cp -l & rm”进行设备内移动:

    cp -alv --backup=numbered tree1/* tree2 &&
    rm -rf tree1/
    
    • -l使用cp硬链接而不是复制,(这也可以防止跨设备操作)
    • --backup=numberedcp用于备份目标目录中的现有文件

    并且要小心这两个问题:

    • 如果您不小心在跨设备目标上运行它,请使用它&&来防止删除未复制的数据。(在 corss-device 情况下cp以“”状态退出1,至少对于 GNU coreutils)
    • .以 " " in开头的文件tree1,如果有,您将丢失它们。
    • 1
  6. Howie Goodell
    2013-06-29T09:09:07+08:002013-06-29T09:09:07+08:00

    哈维尔对 find 的回答效果很好,只是它不会删除原始目录。在末尾添加:

    rmdir $(find . -type d  |grep -v ^\.$)
    
    • 1
  7. Martin M.
    2009-06-12T05:44:52+08:002009-06-12T05:44:52+08:00

    呃

    mv dir1/* dir2/
    

    或者干脆

    rsync -arv --remove-source-files  tree1/* tree2
    

    应该足够了,当有太多条目时,您可能会在某个时候遇到麻烦dir1。

    find sourcedir -maxdepth 1 -exec echo mv {} targetdir/ \;
    

    应该是不错的选择

    find sourcedir -maxdepth 1 -print0 |xargs -0 -I _ echo mv _ targetdir
    find sourcedir -maxdepth1 -exec mv {} targetdir/ +
    

    两者都不是必需的,因为 mv 只需要 2 个选项(源目标),因此在这种情况下您将不得不忍受大量进程。

    • 0
  8. Dave Cheney
    2009-06-13T04:00:02+08:002009-06-13T04:00:02+08:00
    cd /tree1
    mv * /tree2 
    

    这不会移动隐藏的文件或文件夹,但您的原始示例也不会。

    • 0
  9. chris
    2013-06-29T09:39:31+08:002013-06-29T09:39:31+08:00

    我认为 mv 没有做你认为它做的事情。

    一个 unix 文件系统有 3 个组件:

    • 目录条目
    • 索引节点
    • 块

    一个目录入口指向一个 inode。

    inode 有关于文件的元数据(它是文件、目录还是命名管道?谁拥有它?权限是什么?那个 inode 使用什么块?

    块是实际包含文件内容的东西。

    所以——当你“mv”一个文件时,你真正要做的就是取消第一个目录条目的链接并将它重新链接到其他地方。

    snoopy -> inode 333 
    woodstock -> inode 333
    

    没有数据被复制/复制。您创建链接 snoopy,然后创建链接 woodstock,然后删除链接 snoopy。(目录的情况有些不同,因为通常您不能创建硬链接目录,但即便如此,“链接”名称也会发生变化)。

    如果您要从一个文件系统迁移到另一个文件系统怎么办?在过去, mv 只会抛出一个错误并明确表明您不能将文件从一个文件系统移动到另一个文件系统。这些天来,似乎 mv 默默地复制数据然后删除原始数据。

    在过去,由于您无法将数据从一个文件系统移动到另一个文件系统,因此您养成了使用习惯用法的习惯,例如

    焦油 -cf - 。| (cd /new/location && tar -xf -)

    然后你删除旧数据。使用 tar 的部分原因是,在过去,cp 会破坏诸如“这是一个符号链接”和“这是一个硬链接”之类的元数据,而您只需将该文件的新副本作为常规文件获取。即使如此,您仍需要提供“cp”标志来告诉它保留这种结构。

    如果数据从一个文件系统到另一个文件系统,则无法避免“移动”大量数据。使用花哨的 new move 或 rsync 或 tar 或 cpio 都没有关系。

    但是,如果您将所有数据保存在同一个文件系统中,则:

    mv /filesystem-1/big/directory* /filesystem-1/big2/

    这将非常快,因为它只是更改目录条目而不实际移动任何真实数据。

    还有其他问题在起作用,例如如果新位置以及源位置中已经存在文件/目录,该怎么办?

    • 0
  10. antichris
    2021-05-12T10:47:23+08:002021-05-12T10:47:23+08:00

    这个线程中的答案都不适合我的用例,所以我自己想出了一个作为shell script的答案。

    它的核心是这个功能:

    recurse() {
        if [ ! -d "$1" ] || [ ! -e "$2" ]; then
            mv -u "$1" "$2" || exit
            return
        fi
        for entry in "$1/"* "$1/."[!.]* "$1/.."?*; do
            if [ -e "$entry" ]; then
                recurse "$entry" "$2/${entry##"$1/"}"
            fi
        done
    }
    

    您可以这样调用(对于 OP 的用例):

    recurse a/b/c2 a2/b/c2
    

    如果源是目标尚不存在的文件或目录,则只需将其移动到mv -u. 如果源是目标已经存在的目录,它会遍历其内容并递归执行相同的检查,然后对其每个成员进行移动|递归。

    我使用它-u是因为我只需要更新旧文件和保持新文件不变,但您可以将其替换-f为无条件移动或-i交互式移动。或者rm -rf在脚本完成移动内容后不更改任何内容,只更改您的源代码。

    • 0

相关问题

  • 从失败的 UNIX 包升级中恢复的最佳实践?

  • 没有 Unix 管理员就无法生存的工具 [关闭]

  • 大规模的日志传输和聚合

  • 如何及时了解有关 UNIX 软件补丁和升级的最新信息?

  • 您为服务器使用和推荐哪种 UNIX 文件系统?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    Windows 中执行反向 DNS 查找的命令行实用程序是什么?

    • 14 个回答
  • Marko Smith

    如何检查 Windows 机器上的端口是否被阻塞?

    • 4 个回答
  • Marko Smith

    我应该打开哪个端口以允许远程桌面?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch 如何更改我的私钥密码? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve