Linux:copy";。svn";递归目录

Linux:copy";。svn";递归目录,linux,debian,Linux,Debian,我知道有很多关于类似主题的问题,但我还是无法回答 我需要在Debian机器上将所有.svn目录从/var/foo递归复制到/var/foo2: /var/www/foo/.svn /var/www/foo/bar/.svn ... 我尝试了这两个命令,但没有成功: find /var/foo -name ".svn" -type f -exec cp {} ./var/foo2 \; find /var/foo -name ".svn" -type d -exec cp {} /var/foo

我知道有很多关于类似主题的问题,但我还是无法回答

我需要在Debian机器上将所有
.svn
目录从
/var/foo
递归复制到
/var/foo2

/var/www/foo/.svn
/var/www/foo/bar/.svn
...
我尝试了这两个命令,但没有成功:

find /var/foo -name ".svn" -type f -exec cp {} ./var/foo2 \;
find /var/foo -name ".svn" -type d -exec cp {} /var/foo2 \;

一次只复制
foo
中的
svn
目录,另一次不复制任何内容。

给定以下文件结构:

./
./a/
./a/test/
./a/test/2
./b/
./b/3
./test/
./test/1
在要复制的目录中运行以下脚本:

find -type d -iname test -exec sh -c 'mkdir -p "$(dirname ~/tmp2/{})"; cp -r {}/ ~/tmp2/{}' \;
应将所有测试目录复制到
~/tmp2/

关注点:

  • 目录将逐个复制到目标
  • 父目录是预先创建的,这样
    cp
    就不会抱怨目标不存在
  • 使用的不仅仅是
    cp
    ,而是
    cp-r
  • 整个命令用
    sh-c
    包装,这样就可以执行{}上的操作,例如
    dirname
    (这样shell就可以分别为每个目录展开它,而不是在调用
    find
    时展开一次)
~/tmp2
中的结果结构:

./
./a/
./a/test/
./a/test/2
./test/
./test/1

因此,您需要做的就是用
.svn
替换
test
,用所选目录替换
~/tmp2
记住在源目录中运行它,而不是使用绝对路径。

给定以下文件结构:

./
./a/
./a/test/
./a/test/2
./b/
./b/3
./test/
./test/1
在要复制的目录中运行以下脚本:

find -type d -iname test -exec sh -c 'mkdir -p "$(dirname ~/tmp2/{})"; cp -r {}/ ~/tmp2/{}' \;
应将所有测试目录复制到
~/tmp2/

关注点:

  • 目录将逐个复制到目标
  • 父目录是预先创建的,这样
    cp
    就不会抱怨目标不存在
  • 使用的不仅仅是
    cp
    ,而是
    cp-r
  • 整个命令用
    sh-c
    包装,这样就可以执行{}上的操作,例如
    dirname
    (这样shell就可以分别为每个目录展开它,而不是在调用
    find
    时展开一次)
~/tmp2
中的结果结构:

./
./a/
./a/test/
./a/test/2
./test/
./test/1

因此,您需要做的就是用
.svn
替换
test
,用所选目录替换
~/tmp2
请记住在源目录中运行它,而不是使用绝对路径。

我发现对此类操作使用
tar
通常会使代码更具可读性:

$ mkdir /var/www/foo2
$ cd /var/www/foo2
$ find ../foo/ -type d -name .svn -exec tar c \{\} \+ | \
         tar x --strip-components=1
find
将列出名为
.svn
的所有目录,并调用
tar
创建(
c
)一个包含所有这些目录的存档文件(发送到
stdout
)。然后由目标目录中的另一个tar实例提取stdout上的存档(
x
)。归档tar会自动删除相对路径部分(
。/
),但由于我们还想删除第一个路径组件(
foo/
),因此需要添加
——剥离组件


注意:只有当您没有太多要复制的
.svn
目录(超过
$(getconf ARG_MAX)-2
,在我的系统上超过200000个)时,这才起作用。

我发现对此类操作使用
tar
通常会使代码更具可读性:

$ mkdir /var/www/foo2
$ cd /var/www/foo2
$ find ../foo/ -type d -name .svn -exec tar c \{\} \+ | \
         tar x --strip-components=1
find
将列出名为
.svn
的所有目录,并调用
tar
创建(
c
)一个包含所有这些目录的存档文件(发送到
stdout
)。然后由目标目录中的另一个tar实例提取stdout上的存档(
x
)。归档tar会自动删除相对路径部分(
。/
),但由于我们还想删除第一个路径组件(
foo/
),因此需要添加
——剥离组件


注意:只有当您没有太多要复制的
.svn
目录时(超过
$(getconf ARG_MAX)-2
,在我的系统上超过200000),这才有效。

这是一个多么好的答案。谢谢多好的回答啊。谢谢