shell cp命令应忽略某些文件

yws3nbqq  于 2023-11-21  发布在  Shell
关注(0)|答案(5)|浏览(320)

有时我需要执行以下命令

cp -rv demo demo_bkp

字符串
但是我想忽略.git目录中的所有文件。我如何实现这一点?复制.git文件需要很长时间,我不需要这些文件。

yyhrrdl8

yyhrrdl81#

要特别忽略一个git目录,我首先使用try git export
但一般来说,要复制排除某些文件或文件夹的目录树,我建议使用rsync而不是cp。语法基本相同,但rsync有更多的选项,包括一个排除选定文件的选项:

rsync -lrv --exclude=.git demo demo_bkp

字符串
参见the man page了解更多信息。

rslzwgfq

rslzwgfq2#

好吧。打起精神来。这可不妙。

find demo -depth -name .git -prune -o -print0 | cpio -0pdv --quiet demo_bkp

字符串
这是怎么回事?

  1. find demo | cpio -p demo_bkp查找与您想要的任何条件匹配的文件,并使用cpio复制它们(所谓的“传递”模式)。
  2. find -depth更改文件的打印顺序,以匹配cpio想要的顺序。
  3. find -name .git -prune告诉find不要向下递归.git目录。
  4. find -print0 | cpio -0有find use NUL字符(\0)来分隔文件名。这是为了最大限度地提高健壮性,以防出现任何带有空格、换行符或其他不寻常字符的奇怪名称的文件。
  5. cpio -d根据需要创建目录。
  6. cpio -v --quiet打印每个文件名,同时省略cpio通常在末尾打印的“X blocks copied”消息。
dpiehjr4

dpiehjr43#

我想这个可以解决问题:

cd demo
find . -not -path \*/.\* -type d -exec mkdir -p -- ../demo_bkp/{} \;
find . -not -path \*/.\* -type f -exec cp -- {} ../demo_bkp/{} \;

字符串
首先查找并创建每个目录,然后查找并复制每个文件。
请注意,它不适用于特殊文件(符号链接等)。

rslzwgfq

rslzwgfq4#

继续rsync的想法,如果你有很多文件模式要忽略,你可以使用--exclude-from=FILE选项。
--exclude-from=FILE选项接受一个包含排除模式(每行一个模式)的文件[ FILE ],并排除所有与模式匹配的文件。
例如,假设你想将一个目录demo复制到demo_bkp,但是你想忽略包含模式.env.gitcoveragenode_modules的文件。你可以创建一个名为.copyignore的文件,并将模式逐行添加到.copyignore

.env
.git
coverage
node_modules

字符串
然后运行:

rsync -rv --exclude-from=./.copyignore demo demo_bkp


demo将被复制到demo_bkp中,所有与.copyignore中指定的模式匹配的文件都将被忽略。

9o685dep

9o685dep5#

简单的解决方案,可能是最好的运行时,符合OP(谁想要使用cp):

touch /path/to/target/.git
cp -n -ax * /path/to/target/
rm /path/to/target/.git

字符串
这利用了cp-n选项,该选项强制cp不覆盖现有目标。
缺点:与GNU cp一起工作。如果你没有GNU cp,那么cp操作可能会返回一个错误代码(1),这很烦人,因为这样你就不能判断这是否是一个真实的失败。

相关问题