970

是否有一个简单的 shell 命令/脚本支持从存档中排除某些文件/文件夹?

我有一个需要与子目录一起归档的目录,其中包含许多我不需要备份的非常大的文件。

不完全解决方案:

tar --exclude=PATTERN命令与给定模式匹配并排除这些文件,但我需要忽略特定文件和文件夹(完整文件路径),否则可能会排除有效文件。

我还可以使用 find 命令创建文件列表并排除我不想归档的文件并将列表传递给 tar,但这仅适用于少量文件。我有几万。

我开始认为唯一的解决方案是创建一个包含要排除的文件/文件夹列表的文件,然后使用 rsync with--exclude-from=file将所有文件复制到 tmp 目录,然后使用 tar 归档该目录。

有人能想到更好/更有效的解决方案吗?

编辑:Charles Ma的解决方案效果很好。最大的问题是--exclude='./folder' 必须在 tar 命令的开头。完整命令(首先 cd,因此备份相对于该目录):

cd /folder_to_backup
tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .
4

28 回答 28

1256

您可以为 tar 设置多个排除选项

$ tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

等会工作。确保放在源和目标项目之前--exclude

于 2009-06-11T23:11:19.027 回答
144

--exclude您可以使用for tar排除目录。

如果您想存档所有内容,但/usr可以使用:

tar -zcvf /all.tgz / --exclude=/usr

在你的情况下,也许像

tar -zcvf archive.tgz arc_dir --exclude=dir/ignore_this_dir
于 2009-06-11T23:08:46.550 回答
81

使用 tar 从备份中排除文件/目录的可能选项:

使用多种模式排除文件

tar -czf backup.tar.gz --exclude=PATTERN1 --exclude=PATTERN2 ... /path/to/backup

使用包含模式列表的排除文件排除文件

tar -czf backup.tar.gz -X /path/to/exclude.txt /path/to/backup

通过将标记文件放置在应跳过的任何目录中来使用标记排除文件

tar -czf backup.tar.gz --exclude-tag-all=exclude.tag /path/to/backup
于 2012-11-08T00:22:34.477 回答
53

老问题有很多答案,但我发现没有一个对我来说足够清楚,所以我想添加我的尝试。

如果你有以下结构

/home/ftp/mysite/

带有以下文件/文件夹

/home/ftp/mysite/file1
/home/ftp/mysite/file2
/home/ftp/mysite/file3
/home/ftp/mysite/folder1
/home/ftp/mysite/folder2
/home/ftp/mysite/folder3

因此,您想制作一个包含 /home/ftp/mysite 中的所有内容的 tar 文件(将站点移动到新服务器),但这file3只是垃圾,folder3也不需要其中的所有内容,因此我们将跳过这两个。

我们使用格式

tar -czvf <name of tar file> <what to tar> <any excludes>

其中 c = create、z = zip 和 v = verbose(您可以在输入文件时看到它们,这有助于确保没有添加您排除的文件)。和 f= 文件。

所以,我的命令看起来像这样

cd /home/ftp/
tar -czvf mysite.tar.gz mysite --exclude='file3' --exclude='folder3'

请注意,排除的文件/文件夹相对于您的 tar 的根目录(我在这里尝试了相对于 / 的完整路径,但我无法做到这一点)。

希望这会对某人有所帮助(以及我下次谷歌搜索时)

于 2014-05-08T10:48:59.273 回答
31

您可以使用标准的“ant notation”来排除相对目录。
这对我有用,不包括任何 .git 或 node_module 目录:

tar -cvf myFile.tar --exclude=**/.git/* --exclude=**/node_modules/*  -T /data/txt/myInputFile.txt 2> /data/txt/myTarLogFile.txt

myInputFile.txt 包含:

/dev2/java
/dev2/javascript

于 2015-05-14T14:10:55.440 回答
20

此排除模式处理文件名后缀(如 png 或 mp3)以及目录名(如 .git 和 node_modules)

tar --exclude={*.png,*.mp3,*.wav,.git,node_modules} -Jcf ${target_tarball}  ${source_dirname}
于 2015-02-12T20:55:16.623 回答
18

我经历过这种情况,至少在我使用的Cygwin版本的 tar 中(Windows XP Home Edition 上的“CYGWIN_NT-5.1 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin” SP3 机器),选项的顺序很重要。

虽然这种结构对我有用:

tar cfvz target.tgz --exclude='<dir1>' --exclude='<dir2>' target_dir

那个没有用

tar cfvz --exclude='<dir1>' --exclude='<dir2>' target.tgz target_dir

这同时tar --help揭示了以下内容:

tar [OPTION...] [FILE]

所以,第二个命令也应该可以工作,但显然情况并非如此......

最好的rgds,

于 2013-12-31T07:08:41.140 回答
13

我在其他地方发现了这个,所以我不会相信,但它比上面的任何解决方案都比我的 mac 特定问题更好(即使它已关闭):

tar zc --exclude __MACOSX --exclude .DS_Store -f <archive> <source(s)>
于 2010-02-05T21:59:16.747 回答
13

对于 Mac OSX,我必须这样做

tar -zcv --exclude='folder' -f theOutputTarFile.tar folderToTar

注意-f后面的--exclude=

于 2017-05-06T20:07:56.567 回答
11

对于那些对此有疑问的人,某些版本的 tar 只有在排除值中没有 './' 的情况下才能正常工作。

Tar --version

焦油 (GNU 焦油) 1.27.1

有效的命令语法:

tar -czvf ../allfiles-butsome.tar.gz * --exclude=acme/foo

这些将不起作用:

$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=./acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='./acme/foo'
$ tar --exclude=./acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='./acme/foo' -czvf ../allfiles-butsome.tar.gz *
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=/full/path/acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='/full/path/acme/foo'
$ tar --exclude=/full/path/acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='/full/path/acme/foo' -czvf ../allfiles-butsome.tar.gz *
于 2018-04-17T23:28:37.367 回答
10

在阅读了不同版本的所有这些好的答案并为我自己解决了问题之后,我认为有非常小的细节非常重要,并且对于 GNU/Linux 的一般用途来说很少见,这些细节没有得到足够的重视,值得更多的评论。

因此,我不会尝试针对每种情况回答这个问题,而是尝试注册当事情不起作用时在哪里查看。

请务必注意:

  1. 选项的顺序很重要:将 --exclude 放在文件选项和要备份的目录之前与之后是不一样的。这至少对我来说是出乎意料的,因为根据我的经验,在 GNU/Linux 命令中,选项的顺序通常并不重要。
  2. 不同的 tar 版本期望此选项以不同的顺序:例如,@Andrew 的回答表明在 GNU tar v 1.26 和 1.28 中,排除项排在最后,而在我的情况下,对于 GNU tar 1.29,它是另一种方式。
  3. 尾部斜线很重要:至少在 GNU tar 1.29 中,它不应该是任何.

就我而言,对于 Debian stretch 上的 GNU tar 1.29,有效的命令是

tar --exclude="/home/user/.config/chromium" --exclude="/home/user/.cache" -cf file.tar  /dir1/ /home/ /dir3/

引号无关紧要,无论有没有它们都有效。

我希望这对某人有用。

于 2019-05-28T21:41:27.827 回答
10

如果您尝试排除版本控制系统 (VCS) 文件,tar 已经支持两个有趣的选项!:)

  1. 选项:--exclude-vcs

此选项不包括以下版本控制系统使用的文件和目录:CVSRCSSCCSSVNArchBazaarMercurialDarcs.

从 1.32 版开始,以下文件被排除在外:

  • CVS/,以及它下面的一切
  • RCS/,以及它下面的一切
  • SCCS/,以及它下面的一切
  • .git/,以及它下面的一切
  • .gitignore
  • .gitmodules
  • .gitattributes
  • .cvsignore
  • .svn/,以及它下面的一切
  • .arch-ids/,以及它下面的一切
  • {arch}/,以及它下面的一切
  • =RELEASE-ID
  • =meta-update
  • =update
  • .bzr
  • .bzrignore
  • .bzrtags
  • .hg
  • .hgignore
  • .hgrags
  • _darcs

    1. 选项:--exclude-vcs-ignores

.cvsignore当归档某个版本控制系统 (VCS) 下的目录时,从该 VCS 的忽略文件(例如、.gitignore等)中读取排除模式通常很方便。此选项提供了这种可能性。

在归档目录之前,请查看它是否包含以下任何文件:cvsignore.gitignore.bzrignore.hgignore. 如果是这样,请从这些文件中读取忽略模式。

这些模式的处理方式与相应的 VCS 处理它们的方式相同,即:

.cvsignore

包含仅适用于该文件所在目录的 shell 样式的通配模式。文件中不允许有评论。空行被忽略。

.gitignore

包含 shell 样式的 globbing 模式。适用于所在目录.gitfile及其所有子目录。

任何以 a 开头的行#都是注释。反斜杠转义注释字符。

.bzrignore

包含 shell globbing-patterns 和正则表达式(如果以RE:(16) 为前缀。模式影响目录及其所有子目录。

任何以 a 开头的行#都是注释。

.hgignore

包含 posix 正则表达式 (17)。该行syntax: glob切换到 shell globbing 模式。线路syntax: regexp切换回来。注释以 . 开头#。模式会影响目录及其所有子目录。

  1. 例子

tar -czv --exclude-vcs --exclude-vcs-ignores -f path/to/my-tar-file.tar.gz path/to/my/project/

于 2020-05-26T14:01:36.350 回答
8

我同意 --exclude 标志是正确的方法。

$ tar --exclude='./folder_or_file' --exclude='file_pattern' --exclude='fileA'

对我没有立即发现的副作用的警告:在此示例中排除“fileA”将递归搜索“fileA”

示例:具有单个子目录的目录,其中包含同名文件(data.txt)

data.txt
config.txt
--+dirA
  |  data.txt
  |  config.docx
  • 如果使用--exclude='data.txt'存档将不包含任何data.txt文件。如果归档第三方库,例如 node_modules 目录,这可能会导致意外结果。

  • 为避免此问题,请确保提供整个路径,例如--exclude='./dirA/data.txt'

于 2016-07-15T15:56:04.333 回答
6

阅读此线程后,我在 RHEL 5 上做了一些测试,以下是我对 abc 目录进行 tar 处理的结果:

这将排除目录错误和日志以及目录下的所有文件:

tar cvpzf abc.tgz abc/ --exclude='abc/error' --exclude='abc/logs'

在排除目录后添加通配符将排除文件但保留目录:

tar cvpzf abc.tgz abc/ --exclude='abc/error/*' --exclude='abc/logs/*'
于 2014-05-09T21:26:36.640 回答
6

我想展示另一个选项,我曾经得到与之前提供的答案相同的结果,我有一个类似的情况,我想使用du命令将 android studio 项目全部备份到一个 tar 文件中以上传到 media fire要查找大文件,我发现我不需要一些目录,例如: build, linux e .dart_tools 使用 Charles_ma 的第一个答案,我对其进行了一些修改,以便能够从 my 的父目录运行命令安卓目录。

tar --exclude='*/build' --exclude='*/linux' --exclude='*/.dart_tool' -zcvf androidProjects.tar Android/

它就像一个魅力。

附言。抱歉,如果不允许这种答案,如果是这种情况,我将删除。

于 2020-11-21T07:41:14.653 回答
5

为避免在处理数万个文件时'xargs: Argument list too long'使用.find ... | xargs ...findtarfind ... -print0 | tar --null ...

# archive a given directory, but exclude various files & directories 
# specified by their full file paths
find "$(pwd -P)" -type d \( -path '/path/to/dir1' -or -path '/path/to/dir2' \) -prune \
   -or -not \( -path '/path/to/file1' -or -path '/path/to/file2' \) -print0 | 
   gnutar --null --no-recursion -czf archive.tar.gz --files-from -
   #bsdtar --null -n -czf archive.tar.gz -T -
于 2012-03-04T15:18:30.647 回答
4

您还可以根据需要使用“--exclude-tag”选项之一:

  • --排除标签=文件
  • --排除标记全部=文件
  • --exclude-tag-under=文件

将排除托管指定 FILE 的文件夹。

于 2012-09-10T14:08:42.220 回答
3

将 find 命令与 tar append (-r) 选项结合使用。这样,您可以在一个步骤中将文件添加到现有的 tar,而不是通过两次解决方案(创建文件列表,创建 tar)。

find /dir/dir -prune ... -o etc etc.... -exec tar rvf ~/tarfile.tar {} \;
于 2009-06-11T23:03:57.467 回答
3

您可以使用 cpio(1) 创建 tar 文件。cpio 将文件归档到标准输入,因此,如果您已经确定了要用于选择归档文件的 find 命令,请将其通过管道传输到 cpio 以创建 tar 文件:

find ... | cpio -o -H ustar | gzip -c > archive.tar.gz
于 2009-06-12T05:53:17.610 回答
3

gnu tar v 1.26 --exclude 需要在归档文件和备份目录参数之后,不应该有前导或尾随斜杠,并且不喜欢引号(单引号或双引号)。所以相对于要备份的 PARENT 目录,它是:

tar cvfz /path_to/mytar.tgz ./dir_to_backup --exclude=some_path/to_exclude

于 2014-04-14T16:21:50.937 回答
2
tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt

-X 表示包含必须从备份中排除的文件名列表的文件。例如,您可以在此文件中指定 *~ 以在备份中不包含任何以 ~ 结尾的文件名。

于 2018-01-12T10:30:25.033 回答
1

看看这个

tar cvpzf zip_folder.tgz . --exclude=./public --exclude=./tmp --exclude=./log --exclude=fileName
于 2016-07-21T09:56:34.310 回答
1

成功案例: 1)如果给全路径做备份,在exclude中也应该使用全路径。

tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz --exclude='/opt/ABC/csv/ ' --exclude='/opt/ABC/log/ ' /opt/ABC

2) 如果给当前路径做备份,在排除中也应该只使用当前路径。

tar -zcvf backup_27032020.tar.gz --exclude='ABC/csv/ ' --exclude='ABC/log/ ' ABC

失败案例:

  1. 如果给当前路径目录进行备份并忽略完整路径,则无法正常工作

    tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz --exclude='/opt/ABC/csv/ ' --exclude='/opt/ABC/log/ ' ABC

注意:在备份目录之前/之后提及排除是可以的。

于 2020-03-26T21:52:59.923 回答
0

最好的办法是通过 xargs 将 find 与 tar 一起使用(处理大量参数)。例如:

find / -print0 | xargs -0 tar cjf tarfile.tar.bz2
于 2009-06-11T23:04:12.677 回答
0

可能多余的答案,但因为我发现它很有用,这里是:

虽然是 FreeBSD 根目录(即使用 csh),但我想将整个根文件系统复制到 /mnt 但没有 /usr 和(显然)/mnt。这是有效的(我在/):

tar --exclude ./usr --exclude ./mnt --create --file - . (cd /mnt && tar xvd -)

我的全部观点是,有必要(通过放置./指定tar 排除的目录,其中较大目录的一部分被复制。

我的 €0.02

于 2013-09-04T22:35:38.840 回答
0

我没有运气让 tar 排除几个级别深的 5 GB 子目录。最后,我只是使用了 unix Zip 命令。它对我来说更容易。

因此,对于原始帖子中的这个特定示例
(tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz 。)

相当于:

zip -r /备份/文件名.zip。-x 上传/文件夹/**\* 上传/文件夹2/**\*

(注意:这是我最初使用的帮助我的帖子https://superuser.com/questions/312301/unix-zip-directory-but-excluded-specific-subdirectories-and-everything-within-t

于 2013-09-30T20:07:04.463 回答
0

我想在本地主机上有新的前端版本(角度文件夹)。另外,在我的情况下, git 文件夹很大,我想排除它。我需要从服务器下载它,然后解压它才能运行应用程序。

从 /var/lib/tomcat7/webapps 压缩 angular 文件夹,将其移动到名称为 angular.23.12.19.tar.gz 的 /tmp 文件夹

命令 :

tar --exclude='.git' -zcvf /tmp/angular.23.12.19.tar.gz /var/lib/tomcat7/webapps/angular/
于 2019-12-23T09:42:24.693 回答
-1

以下 bash 脚本应该可以解决问题。它使用了Marcus Sundman给出答案。

#!/bin/bash

echo -n "Please enter the name of the tar file you wish to create with out extension "
read nam

echo -n "Please enter the path to the directories to tar "
read pathin

echo tar -czvf $nam.tar.gz
excludes=`find $pathin -iname "*.CC" -exec echo "--exclude \'{}\'" \;|xargs`
echo $pathin

echo tar -czvf $nam.tar.gz $excludes $pathin

这将打印出您需要的命令,您可以将其复制并粘贴回去。可能有一种更优雅的方式可以将其直接提供给命令行。

只需将 *.CC 更改为您想要排除的任何其他常见扩展名、文件名或正则表达式,这应该仍然有效。

编辑

只是添加一点解释;find 生成与所选正则表达式匹配的文件列表(在本例中为 *.CC)。该列表通过 xargs 传递给 echo 命令。这将打印 --exclude '列表中的一个条目'。斜杠 () 是 ' 标记的转义字符。

于 2016-10-28T14:01:35.053 回答