我有一个源目录,例如/ my/source/directory /和目标目录,例如/ my/dest/directory /,我希望镜像一些约束.
我想将符合find命令的某些条件的文件(例如-ctime -2(不到2天))复制到dest目录以镜像它
我想要包含一些前缀,以便我知道它来自哪里,例如/ source/directory
我想用绝对路径做所有这些,所以它不依赖于我运行的目录
我猜想没有cd命令也是很好的做法.
我想要创建子目录,如果它们不存在
所以
/my/source/directory/1/foo.txt -> /my/dest/directory/source/directory/1/foo.txt /my/source/directory/2/3/bar.txt -> /my/dest/directory/source/directory/2/3/bar.txt
我一起攻击了以下命令行,但它看起来有点难看,有人能做得更好吗?
find /my/source/directory -ctime -2 -type f -printf "%P\n" | xargs -IFILE rsync -avR /my/./source/directory/FILE /my/dest/directory/
如果您认为我应该自己添加此命令行作为答案,请发表评论,我不想因为声誉而贪婪.
这非常类似于(封闭的)问题:Bash脚本复制文件而不覆盖.我给出的答案引用了find | cpio
其他答案中提到的解决方案(减去时间标准,但这是'相似'和'相同'之间的差异),并且还概述了使用GNU'tar'的解决方案.
当我在Solaris上测试时,GNU tar和(Solaris)cpio都无法保留ctime设置; 实际上,我不确定是否有办法做到这一点.例如,该touch
命令可以设置atime或mtime或两者 - 但不能设置ctime.该utime()
系统调用也只需要在修改时间或atime的价值观; 它不处理ctime.所以,我相信如果你找到一个保留ctime的解决方案,那么这个解决方案很可能是特定于平台的.(奇怪的例子:破解磁盘设备并编辑inode中的数据 - 不可移植,需要提升权限.)但是,重读这个问题,我发现'保留ctime'不是要求的一部分(phew); 它只是文件是否被复制的标准.
我认为' cd
'操作是必要的 - 但是它们可以完全本地化到脚本或命令行,但是,如引用的问题和下面的命令行所示,其中第二个假定GNU tar.
(cd /my; find source/directory -ctime -2 | cpio -pvdm /my/dest/directory) (cd /my; find source/directory -ctime -2 | tar -cf - -F - ) | (cd /my/dest/directory; tar -xf -)
如果不使用chdir()
(aka cd
),您需要专门的工具或选项来处理动态路径名的操作.
正如Adam Hawes所指出的那样,GNU特定的' find -print0
'和' xargs -0
'非常强大和有效.有趣的是,GNU cpio
可以选择处理' find -print0
',即' --null
'或其简短形式' -0
'的输出.因此,使用GNU find
和GNU cpio
,安全命令是:
(cd /my; find source/directory -ctime -2 -print0 | cpio -pvdm0 /my/dest/directory)
注意:这不会覆盖备份目录下的预先存在的文件.添加-u
到cpio
命令.
同样,GNU tar
支持--null
(显然没有-0
短格式),也可以使用:
(cd /my; find source/directory -ctime -2 -print0 | tar -cf - -F - --null ) | (cd /my/dest/directory; tar -xf -)
使用null终止符对GNU处理文件名非常聪明并且是一项有价值的创新(虽然我最近才意识到这一点,因为SO的礼貌;它已经在GNU tar中存在了至少十年).