递归复制文件夹,不包括某些文件夹

tro*_*ock 191 unix bash shell scripting

我正在尝试编写一个简单的bash脚本,它将包含隐藏文件和文件夹的文件夹的全部内容复制到另一个文件夹中,但我想排除某些特定的文件夹.我怎么能实现这个目标?

Kal*_*son 320

使用rsync:

rsync -av --exclude='path1/to/exclude' --exclude='path2/to/exclude' source destination
Run Code Online (Sandbox Code Playgroud)

请注意,使用sourcesource/不同.尾部斜杠表示将文件夹的内容复制sourcedestination.如果没有尾部斜杠,则表示将文件夹复制sourcedestination.

或者,如果要排除许多目录(或文件),则可以使用--exclude-from=FILE,FILE包含要排除的文件或目录的文件的名称.

--exclude 也可能包含通配符,例如 --exclude=*/.svn*

  • 注意'path1/to/exclude'等是"source"的子目录. (42认同)
  • 我建议添加--dry-run以检查要复制的文件. (8认同)
  • @AmokHuginnsson - 你使用什么系统?我所知道的所有主流 Linux 发行版都默认包含 Rsync,包括 RHEL、CentOS、Debian 和 Ubuntu,我相信 FreeBSD 中也包含 Rsync。 (2认同)
  • 对于 RHEL 派生发行版: yum install rsync ,或在基于 Debian 的发行版上: apt-get install rsync 。除非您完全基于自己的硬件构建服务器,否则这不是问题。rsync 默认安装在我的 Amazon EC2 机器上,以及我的 ZeroLag 和 RackSpace 机器上。 (2认同)
  • 与cp相比,rsync似乎非常慢?至少这是我的经历. (2认同)
  • 例如忽略 git 目录:`rsync -av --exclude='.git/' ../old-repo/ .` (2认同)

Kyl*_*utt 37

使用焦油和管道.

cd /source_directory
tar cf - --exclude=dir_to_exclude . | (cd /destination && tar xvf - )
Run Code Online (Sandbox Code Playgroud)

你甚至可以在ssh中使用这种技术.

  • 当您的容器中没有“rsync”并且您不想安装它时,这是完美的。 (4认同)
  • @Waldheri你错了.这是最好的解决方案.它完全符合OP的要求,并且可以在大多数类似操作系统的*nix的默认安装上运行.在没有文件系统伪影的情况下(在内存中)进行皮重和解决,这个tar + untar的成本可以忽略不计. (3认同)

Pau*_*ce. 9

您可以使用find-prune选项.

一个例子来自man find:

       cd /source-dir
       find . -name .snapshot -prune -o \( \! -name *~ -print0 \)|
       cpio -pmd0 /dest-dir

       This command copies the contents of /source-dir to /dest-dir, but omits
       files  and directories named .snapshot (and anything in them).  It also
       omits files or directories whose name ends in ~,  but  not  their  con?
       tents.  The construct -prune -o \( ... -print0 \) is quite common.  The
       idea here is that the expression before -prune matches things which are
       to  be  pruned.  However, the -prune action itself returns true, so the
       following -o ensures that the right hand side  is  evaluated  only  for
       those  directories  which didn't get pruned (the contents of the pruned
       directories are not even visited, so their  contents  are  irrelevant).
       The  expression on the right hand side of the -o is in parentheses only
       for clarity.  It emphasises that the -print0 action  takes  place  only
       for  things  that  didn't  have  -prune  applied  to them.  Because the
       default `and' condition between tests binds more tightly than -o,  this
       is  the  default anyway, but the parentheses help to show what is going
       on.


Jac*_*ack 7

快速开始

\n

跑步:

\n
rsync -av --exclude=\'path1/in/source\' --exclude=\'path2/in/source\' [source]/ [destination]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

笔记

\n
    \n
  • -avr将创建一个名为 的新目录[destination]
  • \n
  • sourcesource/创建不同的结果:\n
      \n
    • source\xe2\x80\x94 将源内容复制到目标。
    • \n
    • source/\xe2\x80\x94 将文件夹源复制到目标。
    • \n
    \n
  • \n
  • 要排除许多文件:\n
      \n
    • --exclude-from=FILE\xe2\x80\x94FILE是包含要排除的其他文件或目录的文件的名称。
    • \n
    \n
  • \n
  • --exclude还可能包含通配符:\n
      \n
    • 例如--exclude=*/.svn*
    • \n
    \n
  • \n
\n

修改自:/sf/answers/153615031/

\n
\n

例子

\n

起始文件夹结构:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 destination\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fileToCopy.rtf\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fileToExclude.rtf\n
Run Code Online (Sandbox Code Playgroud)\n

跑步:

\n
rsync -av --exclude=\'fileToCopy.rtf\' source/ destination\n
Run Code Online (Sandbox Code Playgroud)\n

结束文件夹结构:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 destination\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fileToExclude.rtf\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 source\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fileToCopy.rtf\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fileToExclude.rtf\n
Run Code Online (Sandbox Code Playgroud)\n