【发布时间】:2011-05-03 16:54:10
【问题描述】:
我想为我们的多 TB 文件服务器的结构创建一个克隆。我知道 cp --parents 可以移动文件及其父结构,但是有没有办法完整地复制目录结构?
我想复制到一个 linux 系统,我们的文件服务器是 CIFS 挂载在那里的。
【问题讨论】:
-
上述评论帖子中的rsync解决方案看起来更整洁。
我想为我们的多 TB 文件服务器的结构创建一个克隆。我知道 cp --parents 可以移动文件及其父结构,但是有没有办法完整地复制目录结构?
我想复制到一个 linux 系统,我们的文件服务器是 CIFS 挂载在那里的。
【问题讨论】:
你可以这样做:
find . -type d > dirs.txt
创建目录列表,然后
xargs mkdir -p < dirs.txt
在目标上创建目录。
【讨论】:
find . -type d -print0 >dirs.txt 和xargs -0 mkdir -p <dirs.txt。这将导致两个命令都使用空值而不是空格作为分隔符。
xargs 在开始处理成百上千的订单时可能会超过系统的最大命令长度,请谨慎使用。 (使用getconf ARG_MAX 查找命令长度限制。)对于很多目录,您可能需要编写一个脚本来循环输出。
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
【讨论】:
rsyncthis SO questionthis SO questionChen Levy 的解决方案
-- 是标准的 GNU 实用程序选项终止符。它的意思是“嘿,mkdir,这之后的任何参数,它都不是一个标志,所以把它当作一个文件参数,即使它以'-'字符开头。”
这是一个使用 rsync 的简单解决方案:
rsync -av -f"+ */" -f"- *" "$source" "$target"
【讨论】:
rsync -a --include '*/' --exclude '*' "$source" "$target"
我不知道您是否正在寻找 Linux 上的解决方案。如果是这样,你可以试试这个:
$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
【讨论】:
这会复制目录和文件属性,但不会复制文件数据:
cp -R --attributes-only SOURCE DEST
如果你对文件不感兴趣,你可以删除它们:
find DEST -type f -exec rm {} \;
【讨论】:
这行得通:
find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I {} mkdir -p <DEST_DIR>"/{}"
只需替换 SOURCE_DIR 和 DEST_DIR。
【讨论】:
1行解决方案:
find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
【讨论】:
以下解决方案在各种环境中对我都很有效:
sourceDir="some/directory"
targetDir="any/other/directory"
find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
【讨论】:
这甚至解决了空格问题:
在原始/源目录中:
find . -type d -exec echo "'{}'" \; > dirs2.txt
然后在新创建的目录中重新创建它:
mkdir -p <../<SOURCEDIR>/dirs2.txt
【讨论】:
将target_dir 和source_dir 替换为适当的值:
cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p "{}"
在 OSX+Ubuntu 上测试。
【讨论】:
如果您可以从 Windows 机器获得访问权限,则可以使用 xcopy 和 /T 和 /E 来仅复制文件夹结构(/E 包括空文件夹)
[编辑!]
这个使用 rsync 重新创建目录结构,但没有文件。 http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html
实际上可能更好:)
【讨论】:
Sergiy Kolodyaznyy 的 Python 脚本 发布于Copy only folders not files?:
#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
os.makedirs(os.path.join(sys.argv[1],i))
或从外壳:
python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
仅供参考:
【讨论】:
另一种方法是使用tree,它非常方便,可以根据其强大的选项导航目录树。有仅目录、排除空目录、排除带有模式的名称、仅包含带有模式的名称等选项。查看man tree
优点:你可以编辑或查看列表,或者如果你做大量脚本并经常创建一批空目录
方法:使用tree 创建目录列表,将该列表用作mkdir 的参数输入
tree -dfi --noreport > some_dir_file.txt
-dfi 仅列出目录,打印每个名称的完整路径,使树不打印缩进行,
--noreport 在树列表的末尾省略文件和目录报告的打印,只是为了使输出文件不包含任何绒毛
然后转到你想要空目录的目的地并执行
xargs mkdir < some_dir_file.txt
【讨论】:
find source/ -type f | rsync -a --exclude-from - source/ target/
仅复制具有相关权限和所有权的目录
【讨论】:
简单的方法:
for i in `find . -type d`; do mkdir /home/exemplo/$i; done
【讨论】:
cd oldlocation
find . -type d -print0 | xargs -0 -I{} mkdir -p newlocation/{}
您也可以只创建顶级目录:
cd oldlocation
find . -maxdepth 1 -type d -print0 | xargs -0 -I{} mkdir -p newlocation/{}
【讨论】:
这是 php 中的一个解决方案:
使用以下内容创建一个类似syncDirs.php 的文件:
<?php
foreach (new DirectoryIterator($argv[1]) as $f) {
if($f->isDot() || !$f->isDir()) continue;
mkdir($argv[2].'/'.$f->getFilename(), $f->getPerms());
chown($argv[2].'/'.$f->getFilename(), $f->getOwner());
chgrp($argv[2].'/'.$f->getFilename(), $f->getGroup());
}
以具有足够权限的用户身份运行它:
sudo php syncDirs.php /var/source /var/destination
【讨论】: