在 Linux 中合并 2 个目录树而不复制?

baj*_*ife 34 linux files bash

我有两个布局相似的目录树,即

.
 |-- dir1
 |   |-- a
 |   |   |-- file1.txt
 |   |   `-- file2.txt
 |   |-- b
 |   |   `-- file3.txt
 |   `-- c
 |       `-- file4.txt
 `-- dir2
     |-- a
     |   |-- file5.txt
     |   `-- file6.txt
     |-- b
     |   |-- file7.txt
     |   `-- file8.txt
     `-- c
         |-- file10.txt
         `-- file9.txt
Run Code Online (Sandbox Code Playgroud)

我想合并 dir1 和 dir2 目录树以创建:

 merged/
 |-- a
 |   |-- file1.txt
 |   |-- file2.txt
 |   |-- file5.txt
 |   `-- file6.txt
 |-- b
 |   |-- file3.txt
 |   |-- file7.txt
 |   `-- file8.txt
 `-- c
     |-- file10.txt
     |-- file4.txt
     `-- file9.txt
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用“cp”命令执行此操作,但我想移动文件而不是复制,因为我要合并的实际目录非常大并且包含大量文件(数百万)。如果我使用“mv”,由于目录名称冲突,我会收到“文件存在”错误。

更新:您可以假设两个目录树之间没有重复的文件。

kar*_*ore 29

rsync -ax --link-dest=dir1/ dir1/ merged/
rsync -ax --link-dest=dir2/ dir2/ merged/
Run Code Online (Sandbox Code Playgroud)

这将创建硬链接而不是移动它们,您可以验证它们是否被正确移动,然后删除dir1/dir2/

  • 的种类。它实际上并不复制任何磁盘使用情况,它只是创建另一个指向同一块磁盘的指针,并且实际上并不“复制”任何数据。(请参阅 http://en.wikipedia.org/wiki/Hard_links)但是,它确实必须为每个文件执行一次该操作。但这基本上就是所有这些答案的结果,因为您不能只移动一个目录。 (9认同)
  • 一个警告:使 `--link-dest` 路径成为绝对路径,或相对于 `merged/`;否则它会复制。 (5认同)
  • 不过,这仅在它们位于同一文件系统上时才有效。如果它们在同一个文件系统上,带有删除选项的 rsync 会移动吗?(也就是说,只更改目录信息,而不移动文件)。 (2认同)

小智 21

奇怪的是没有人注意到cp有选项-l

-l, --link
       硬链接文件而不是复制

你可以做类似的事情

% mkdir 合并
% cp -rl dir1/* dir2/* 合并
% rm -r 目录*
% 树合并 
合并
???一种
? ???文件1.txt
? ???文件2.txt
? ???文件5.txt
? ???文件6.txt
???乙
? ???文件3.txt
? ???文件7.txt
? ???文件8.txt
???C
    ???文件10.txt
    ???文件4.txt
    ???文件9.txt

13个目录,0个文件

  • 更正确的说法是它不能跨文件系统工作,因为文件系统可以跨越多个硬盘驱动器。此外,如果 op 想要避免复制文件,那么 `cp -l` 不能跨文件系统工作是一件好事。 (4认同)
  • 你可能想使用 `cp -a`(`cp -RPp` 的同义词)来保留文件的所有属性并避免跟随符号链接:这里的命令变成了 `cp -al dir1/* dir2/* merge`。 (2认同)

Tob*_*obu 5

您可以为此使用重命名(又名 prename,来自 perl 包)。请注意,该名称不一定是指我在 debian/ubuntu 之外描述的命令(尽管如果需要,它是一个可移植的 perl 文件)。

mv -T dir1 merged
rename 's:^dir2/:merged/:' dir2/* dir2/*/*
find dir2 -maxdepth 1 -type d -empty -delete
Run Code Online (Sandbox Code Playgroud)

您还可以选择使用 vidir(来自 moreutils),并从您喜欢的文本编辑器中编辑文件路径。