Linux: 递归复制“.svn”目录
Linux: copy ".svn" directories recursively
我知道有很多关于类似 topcis 的问题,但我仍然无法解决这个问题。
我需要在 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
因此,您需要做的就是将 test
替换为 .svn
并将 ~/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
) 与所有这些目录。然后 target 目录中的另一个 tar 实例提取 (x
) stdout 上的存档。相对路径部分 (../
) 被归档 tar 自动删除,但由于我们还想删除第一个路径部分 (foo/
),我们需要添加 --strip-components
.
注意:只有当您没有非常多 .svn
个要复制的目录(超过 $(getconf ARG_MAX)-2
,在我的系统大于200000)。
我知道有很多关于类似 topcis 的问题,但我仍然无法解决这个问题。
我需要在 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
因此,您需要做的就是将 test
替换为 .svn
并将 ~/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
) 与所有这些目录。然后 target 目录中的另一个 tar 实例提取 (x
) stdout 上的存档。相对路径部分 (../
) 被归档 tar 自动删除,但由于我们还想删除第一个路径部分 (foo/
),我们需要添加 --strip-components
.
注意:只有当您没有非常多 .svn
个要复制的目录(超过 $(getconf ARG_MAX)-2
,在我的系统大于200000)。