我想将 svn 存储库中修改后的文件复制到另一个目录,同时保留其目录结构。
阅读完 awk 和 xargs 手册页后,我找到了一种获取更改文件名的方法,如下所示:
$ svn status -q | awk '{ print $2 }' | xargs -d \\n -I '{}' cp '{}' /tmp/xen/
但问题是,这样目录结构就不会被保留,我想复制这样的文件:
./common/superp.c -> /tmp/xen/common/superp.c
./common/m2mgr.c -> /tmp/xen/common/m2mgr.c
./common/page_alloc.c -> /tmp/xen/common/page_alloc.c
./arch/x86/mm.c -> /tmp/xen/arch/x86/mm.c
./arch/x86/mm/shadow/private.h -> /tmp/xen/arch/x86/mm/shadow/private.h
我尝试将 cp 命令更改为cp'{}'/tmp/xen/'{}'但它说没有这样的文件或目录。 是否有任何方法可以让 cp 复制文件并在需要时创建目录? 请指出此命令链是否可以简化。 :-)
感谢大家的回复。由于目录有点大,我不想使用 cp -R 或 rsync 复制整个目录。CK 建议使用 tar 管道,这很有用。
svn status -q | awk '{ print $2 }' | xargs tar cf - | (cd /tmp/xen/; tar xvf -)
答案1
一些快速的想法:
- 添加 mkdir -p $(dirname FILE)
- 你能用焦油管把一切都整理好吗?
编辑
tar -cf archive.tar `svn status -q | awk '{print $2}'`
应创建已修改文件的存档。然后:
tar -xf archive.tar -C /tmp/xen
应该将其放在您想要的位置。如果需要一步完成,那也是可能的。
答案2
rsync 使操作变得非常简单,它是我通常用来复制整个目录结构的工具:
rsync -av /home/source/svn/repo /home/dest/svn/
这将在 /home/dest/svn 目录中创建 repo 目录及其所有内容,因此您将拥有 /home/dest/svn/repo/...
例如:
rsync -rv ./ /tmp/xen/
-a,将保留时间戳并在其他内容中进行递归,“man rsync”。
意识到我读错了问题后更新:
模拟目录结构(tar 替代方案):
rsync -av --include='*/' --exclude='*' source destination
然后复制 20 分钟前的文件:
find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/
答案3
以下是供参考的一行:
svn status -q | awk '{print $2}' | xargs tar -c | tar -xC /tmp/xen
英文版本:
- 使用 获取感兴趣的文件列表
svn status -q
,通过管道传输到... - awk 提取包含文件路径的列:
awk '{print $2}'
- xargs 用于将文件列表提供给 tar,然后 tar 将文件的 tarball 发送到 stdout:
xargs tar -c
- 该文件会被立即重新提取 (
-x
) 到目标目录 (-C path
) 中:tar -xC /tmp/xen
答案4
rsync -a 不会创建深度超过 1 的新目录,因此 rsync 只是部分解决方案,例如不适合我(我在 Google 上找到了当中间缺少几个目录时如何将目录 rsync 到某个远程层次结构的答案)
编辑:我的意思是,我有源目录:/home/user/projects/homework/1/1.1/ 并且我想将它 rsync 到远程:/home/user/projects/homework/1/1.1/...但是目标还没有目录 /home/user/projects/homework...并且我不想传输源机器中位于 /home/user/projects/ 中的其他子目录
编辑2:找到了一种方法,使用 rsync --relative 选项:上面的例子将是这样的:
cd /home/projects/ ; rsync -aR homework/1/1.1 用户@remote:/home/user/projects/