将文件夹结构(不含文件)从一个位置复制到另一个位置

Posted

技术标签:

【中文标题】将文件夹结构(不含文件)从一个位置复制到另一个位置【英文标题】:Copy folder structure (without files) from one location to another 【发布时间】:2011-05-03 16:54:10 【问题描述】:

我想为我们的多 TB 文件服务器的结构创建一个克隆。我知道 cp --parents 可以移动文件及其父结构,但是有没有办法完整地复制目录结构?

我想复制到一个 linux 系统,我们的文件服务器是 CIFS 挂载在那里的。

【问题讨论】:

Rsync how to include directories but not files?的可能重复 上述评论帖子中的rsync解决方案看起来更整洁。 【参考方案1】:

你可以这样做:

find . -type d > dirs.txt

创建目录列表,然后

xargs mkdir -p < dirs.txt

在目标上创建目录。

【讨论】:

如果目录名称中有空格,此解决方案将不起作用。 @Jealie 将命令更改为find . -type d -print0 &gt;dirs.txtxargs -0 mkdir -p &lt;dirs.txt。这将导致两个命令都使用空值而不是空格作为分隔符。 xargs 在开始处理成百上千的订单时可能会超过系统的最大命令长度,请谨慎使用。 (使用getconf ARG_MAX 查找命令长度限制。)对于很多目录,您可能需要编写一个脚本来循环输出。 那么权限和属性会被保留吗?? @TrevorBoydSmith:感谢您的评论。最初的问题没有提到需要保留权限、所有权或属性的任何内容。正如您所提到的,这样做需要一个不同的解决方案,但以上内容足以回答所提出的问题。【参考方案2】:
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/ \;

【讨论】:

我的最佳答案是 find。否则你可以试试rsyncthis SO questionthis SO questionChen Levy 的解决方案 --mkdir 的选项是什么? -- 是标准的 GNU 实用程序选项终止符。它的意思是“嘿,mkdir,这之后的任何参数,它都不是一个标志,所以把它当作一个文件参数,即使它以'-'字符开头。” 这个答案也不保留目录权限和属性。 Use rynsc to preserve the permissions and attributes【参考方案3】:

这是一个使用 rsync 的简单解决方案:

rsync -av -f"+ */" -f"- *" "$source" "$target"
一行 空格没有问题 保留权限

I found this solution there

【讨论】:

相同但更具可读性rsync -a --include '*/' --exclude '*' "$source" "$target" 此解决方案的问题是:我的文件夹包含数千个文件,而 rsync 仅同步十几个文件夹就需要很长时间。【参考方案4】:

我不知道您是否正在寻找 Linux 上的解决方案。如果是这样,你可以试试这个:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir

【讨论】:

cpio 似乎对我不起作用,至少使用您指定的参数。 @r00fus - 请阅读 cpio 手册或参考 gnu.org/software/cpio【参考方案5】:

这会复制目录和文件属性,但不会复制文件数据:

cp -R --attributes-only SOURCE DEST

如果你对文件不感兴趣,你可以删除它们:

find DEST -type f -exec rm  \;

【讨论】:

会很好,但你忘了提到保存所有权、时间戳和权限。因此它在 Win7/cygwin 中产生了混乱 - NULL_SID 用户、错误的权限顺序、无法编辑权限等并且无法访问生成的文件结构。 我应该认为责任完全在于试图使用 Windows 进行实际工作的人。 cp -R --attributes-only --preserve=all --parents -v SOURCE DEST【参考方案6】:

这行得通:

find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I  mkdir -p <DEST_DIR>"/"

只需替换 SOURCE_DIR 和 DEST_DIR。

【讨论】:

【参考方案7】:

1行解决方案:

find . -type d -exec mkdir -p /path/to/copy/directory/tree/ \;

【讨论】:

【参考方案8】:

以下解决方案在各种环境中对我都很有效:

sourceDir="some/directory"
targetDir="any/other/directory"

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p

【讨论】:

【参考方案9】:

这甚至解决了空格问题:

在原始/源目录中:

find . -type d -exec echo "''" \; > dirs2.txt

然后在新创建的目录中重新创建它:

mkdir -p <../<SOURCEDIR>/dirs2.txt

【讨论】:

【参考方案10】:

target_dirsource_dir 替换为适当的值:

cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p ""

在 OSX+Ubuntu 上测试。

【讨论】:

【参考方案11】:

如果您可以从 Windows 机器获得访问权限,则可以使用 xcopy 和 /T 和 /E 来仅复制文件夹结构(/E 包括空文件夹)

http://ss64.com/nt/xcopy.html

[编辑!]

这个使用 rsync 重新创建目录结构,但没有文件。 http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

实际上可能更好:)

【讨论】:

很遗憾,我们的 CIFS 服务文件服务器没有运行 windows,因此无法执行 win 命令。 谢谢,rsync 方法对我来说效果很好。它也与目录名称中的空格兼容。【参考方案12】:

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

仅供参考:

Copy top level folder structure without copying files in linux How do I copy a directory tree but not the files in Linux?

【讨论】:

【参考方案13】:

另一种方法是使用tree,它非常方便,可以根据其强大的选项导航目录树。有仅目录、排除空目录、排除带有模式的名称、仅包含带有模式的名称等选项。查看man tree

优点:你可以编辑或查看列表,或者如果你做大量脚本并经常创建一批空目录

方法:使用tree 创建目录列表,将该列表用作mkdir 的参数输入

tree -dfi --noreport > some_dir_file.txt

-dfi 仅列出目录,打印每个名称的完整路径,使树不打印缩进行,

--noreport 在树列表的末尾省略文件和目录报告的打印,只是为了使输出文件不包含任何绒毛

然后转到你想要空目录的目的地并执行

xargs mkdir < some_dir_file.txt

【讨论】:

【参考方案14】:
find source/ -type f  | rsync -a --exclude-from - source/ target/

仅复制具有相关权限和所有权的目录

【讨论】:

【参考方案15】:

简单的方法:

for i in `find . -type d`; do mkdir /home/exemplo/$i; done

【讨论】:

【参考方案16】:
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/

【讨论】:

此解决方案在 LinuxMint 20.2 上完美运行,与 10 年前验证的答案不同。谢谢!【参考方案17】:

这是 php 中的一个解决方案:

复制目录(不是递归的,只有一层) 保留权限 与 rsync 解决方案不同,即使目录包含数千个文件也很快,因为它甚至不会进入文件夹 没有空格问题 应该易于阅读和调整

使用以下内容创建一个类似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

【讨论】:

您不必喜欢 PHP,也不必使用它。但是 OP 没有具体说明他是否想要任何特定语言的解决方案,不管你喜不喜欢,PHP 无论如何都安装在许多 Linux 系统上,因为 80% 的网络使用 PHP (w3techs.com/technologies/details/pl-php/all/all)。

以上是关于将文件夹结构(不含文件)从一个位置复制到另一个位置的主要内容,如果未能解决你的问题,请参考以下文章

如何将文件从一个位置复制到另一个位置?

如何将文件从一个位置复制到另一个位置?

如何使用 phonegap 将文件从一个位置移动/复制到另一个位置

仅复制文件夹

如何将具有属性/权限的目录从一个位置复制到另一个位置?

如何将 chrome 书签从单个桌面上的不同用户配置文件复制到另一个网络位置