Shell命令到tar目录,不包括某些文件/文件夹


810

是否有一个简单的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 .

120
令我着迷的另一件事可能值得一提:排除文件夹末尾的斜杠将导致tar 根本不排除这些文件夹。
Rekhyt

7
@Rekhyt谢谢,我盯着命令
看了

9
似乎--exclude的位置取决于tar的版本。对于tar 1.23,--exclude需要在主要命令之后。
乔尔·马修

2
不要忘记“'”(引号)。
Meetai.com 2013年

3
--exclude不一定要是第一个,但它必须位于源目录之前的某个位置(在Cygwin上用tar 1.29测试)。
wortwart

Answers:


1038

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

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

等会工作。请务必--exclude 之前的源和目标项目。


78
这个答案看起来像--exclude首先出现... tar cvfpz ../stuff.tgz --exclude ='node_modules'--exclude ='。git'。
詹姆斯·奥布莱恩2014年

13
例如,如果您要备份wordpress项目文件夹(不包括上载文件夹),则可以使用以下命令:tar -cvf wordpress_backup.tar wordpress --exclude = wp-content / uploads
shasi kanth

12
我想出了以下命令:tar -zcv --exclude='file1' --exclude='patter*' --exclude='file2' -f /backup/filename.tgz . 请注意,该-f标志必须位于tar文件之前,请参见:superuser.com/a/559341/415047
Alfred Bez 2015年

21
排除目录末尾的“ /”将导致其失败。我猜tar认为结尾的/是要排除的目录名称的一部分。坏:--exclude = mydir /好的:--exclude = mydir
Josiah

4
>确保在源项目和目标项目之前放置--exclude。或使用排除的绝对路径:tar -cvpzf backups / target.tar.gz --exclude ='/ home / username / backups'/ home / username
Cloudinsidr.com上的NightKnight,2016年

131

您可以使用--excludetar 排除目录。

如果要存档所有内容/usr,则可以使用:

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

在你的情况下,也许像

tar -zcvf archive.tgz arc_dir --exclude=dir/ignore_this_dir

17
为了明确起见,您可以对--exclude使用完整路径。
约翰·索德伯格

2
在某些情况下,要求
--exlude

68

使用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

3
参数的顺序似乎很重要,这种形式对我有用。
cstamas '18 -10-1

1
我也是。对于Ubuntu 16.04上的tar(GNU tar)1.28,仅此特定顺序的参数有效。
alvaroreig

43

这个旧问题有很多答案,但是我发现没有一个问题对我来说足够清楚,因此我想尝试一下。

如果您具有以下结构

/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 =创建,z =压缩和v =详细(您可以在输入文件时看到它们,这对于确保未添加任何排除的文件很有用)。和f =文件。

因此,我的命令将如下所示

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

请注意,排除的文件/文件夹是相对于tar的根目录的(我在这里尝试了相对于/的完整路径,但我无法执行此操作)。

希望这对某人有帮助(下次我用Google搜索时也会对我有帮助)


6
这个答案肯定对我有帮助!对我来说,陷阱是我的命令看起来像tar -czvf mysite.tar.gz mysite --exclude='./mysite/file3' --exclude='./mysite/folder3',但这并没有排除任何内容。
阿尼什·拉马斯瓦米

2
您的样本与我遇到的问题非常相似!谢谢!
Qorbani

2
很好,很清楚,谢谢。对我来说,问题是其他答案包括相对路径的绝对值。但是,您要做的就是添加要排除的文件夹的名称。
休伯特

2
这是一个更加明确的答案。由于这个例子,我能够使它正常工作,因为起初路径令人困惑。谢谢一群!
fagiani

2
有效!请记住不要在排除项后面加上斜杠。例如,当“ file3”或“ file3 / subfolder”起作用时,“ file3 /”和“ file3 / subfolder /”却不起作用!
lucaferrario

24

您可以使用标准的“蚂蚁符号”来排除相对目录。
这对我有用,并且不包括任何.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


4
我相信这要求globstar必须启用Bash shell选项变量。用检查shopt -s globstar。我认为默认情况下,在大多数基于unix的OS上都是关闭的。在Bash手册中:“ globstar: 如果设置,则**在文件名扩展上下文中使用的模式将匹配所有文件以及零个或多个目录和子目录。如果该模式后跟一个'/',则仅目录和子目录匹配。
not2qubit

15

我已经经历过,至少在Windows XP Home Edition上使用的Cy 的Cygwin版本的tar(“ 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]

因此,第二个命令也应该起作用,但显然并非如此……

最好的RGB


5
只是要添加到上面,重要的是要排除的目录不应包含最后的反斜杠。因此,--exclude ='/ path / to / exclude / dir'正确的,-- exclude ='/ path / to / exclude / dir /'WRONG
GeertVc 2013年

17
这是因为目标档案target.tgz是f开关的参数,应该遵循它
Valentino

14

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

tar --exclude={*.png,*.mp3,*.wav,.git,node_modules} -Jcf ${target_tarball}  ${source_dirname}

谢谢-那就是我想要的:)
亚历山大·布。

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 *

10

我在其他地方找到了这个,所以我不会相信,但是它比上面针对我的mac机特定问题的任何解决方案都更有效(即使已关闭):

tar zc --exclude __MACOSX --exclude .DS_Store -f <archive> <source(s)>

2
感谢您提供此答案,达尔文(tarwin)上的tar肯定具有不同的语法,这让我很生气,为什么其他答案中的“ --exclude = blah”无效。这在Mac上效果很好。
迈克尔

1
不要忘记COPYFILE_DISABLE=1使用tar时,否则您可能会在tar包中获得._文件
Benoit Duffez,2016年

感谢您提供答案。包含指向您找到答案的源的链接总是很不错的。奖励:如果来源是来自另一个stackoverflow或stackexchange帖子,您将获得额外的业力(无论是积分还是徽章-我不记得是哪个)。无论哪种方式,他们都会微笑,每个人都会赢。没有缺点:-)如果想要搜索更多信息,它也可以帮助人们。有时,人们会仅仅因为您包含了源链接而投票赞成。最后,分享解决的特定问题或为什么这是一个更好的解决方案,这可能会帮助其他遇到独特问题的人。
SherylHohman

8

对于Mac OSX,我必须要做

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

注意-f--exclude=


6

我同意--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'存档,则将不包含EITHER data.txt文件。如果归档第三方库(例如node_modules目录),则可能导致意外结果。

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


5

为避免在处理成千上万个文件时'xargs: Argument list too long'由于使用造成的可能错误find ... | xargs ...,您可以将的输出find直接tar通过管道传递给using find ... -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 -

您可以像这样引用'exclude'字符串:'somedir / filesdir / *',那么shell不会扩展星号和其他白色字符。
Znik 2014年

xargs -n 1是避免xargs: Argument list too long错误的另一种选择;)
Tuxdude 2014年

5

阅读此线程后,我在RHEL 5上做了一些测试,这是我为abc目录加油的结果:

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

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

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

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

在上面的第二个示例中,每个exclude子句中的最后一个斜杠后应有星号,但该帖子未使用它们。
麦克,21:

4

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

find /dir/dir -prune ... -o etc etc.... -exec tar rvf ~/tarfile.tar {} \;

4

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

  • --exclude-tag =文件
  • --exclude-tag-all =文件
  • --exclude-tag-under =文件

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


4

在阅读了所有不同版本的所有好的答案并为自己解决了问题之后,我认为其中有一些非常重要的细节,对于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/

引号无关紧要,无论是否使用引号都可以。

我希望这对某人有用。


谢谢您的回答。我一直在寻找(感觉很长时间)解决方案,您的回答引导了我正确的方向。但是,在我的情况下(Ubuntu 18.04.3,Tar 1.29),我只能使其与添加文件夹名称一起使用,而不能添加路径,例如:tar --exclude = folder1 --exclude = folder2 -czvf / opt / archieve。 tgz文件夹
Nitai

2

您可以使用cpio(1)创建tar文件。cpio将文件存储在stdin上,因此,如果您已经找到要用于选择存档文件的find命令,请将其通过管道传输到cpio中以创建tar文件:

find ... | cpio -o -H ustar | gzip -c > archive.tar.gz

2

gnu tar v 1.26 – --exclude需要在归档文件和备份目录参数之后出现,不应有任何前导或尾部斜杠,并且不希望使用引号(单引号或双引号)。因此,相对于要备份的PARENT目录,它是:

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


经过大量的实验,我在中的命令中发现了差不多相同的东西tar (GNU tar) 1.28
PicoutputCls

2
tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt

-X表示一个文件,其中包含必须从备份中排除的文件名列表。对于实例,您可以在此文件中指定*〜在备份中不包含任何以〜结尾的文件名。


我认为,这是最好的解决方案,因为即使在这种情况下也可以使用,但排除项的数量很大。还可以在选项包中包括X选项,因此最短形式可能是:tar cXvfJ EXCLUDE-LIST ARCHIVE.tar.xz SOURCE-FOLDER
Kai Petzke

0

最好的选择是通过xargs将find与tar配合使用(以处理大量参数)。例如:

find / -print0 | xargs -0 tar cjf tarfile.tar.bz2

4
这可能会导致tar被多次调用-并且还会重复打包文件。正确的是:find / -print0 | tar -T- --null --no-recursive -cjf tarfile.tar.bz2
约根森

我在某处读到,在使用时xargs,应该使用tar r选项,而不是c因为当find实际发现大量结果时,xargs会将这些结果(基于本地命令行参数限制)分成小块并在每个部分调用tar。这将导致一个归档文件,其中包含返回的最后一个块,xargs而不是find命令找到的所有结果。
斯特凡,2015年

0

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

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

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

我的全部观点是,有必要(通过输入./)将要排除的目录复制到tar中,以指定 tar。

我的€0.02


0

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

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

等效为:

zip -r /backup/filename.zip。-x上传/文件夹/ ** \ *上传/文件夹2 / ** \ *

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


3
当心:zip不会打包空目录,但是tar会打包!
t0r0X 2014年

0

一探究竟

tar cvpzf zip_folder.tgz . --exclude=./public --exclude=./tmp --exclude=./log --exclude=fileName

0

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

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

命令:

tar --exclude='.git' -zcvf /tmp/angular.23.12.19.tar.gz /var/lib/tomcat7/webapps/angular/

0

成功案例:1)如果给出完整路径进行备份,则在排除中也应使用完整路径。

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. 如果给currentpath目录进行备份并忽略完整路径,则无法正常工作

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

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


0

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

  1. 选项:-- exclude-vcs

这个选项排除按照版本控制系统中的文件和目录:CVSRCSSCCSSVNArchBazaarMercurial,和Darcs

从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

当归档是在一些版本控制系统(VCS)目录,这是很方便的从这个VCS”读排除模式忽略文件(例如.cvsignore.gitignore等),这个选项提供了这样的可能性。

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

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

.cvsignore

包含仅适用于此文件所在目录的外壳样式的滚动模式。文件中不允许有注释。空行将被忽略。

.gitignore

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

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

.bzrignore

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

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

.hgignore

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

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


-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命令。这将打印-排除“列表中的一个条目”。斜杠()是'标记的转义字符。


1
对于大多数shell脚本而言,要求交互式输入是一个糟糕的设计选择。让它读取命令行参数,而不是和你的shell的标签完成,完成历史,历史编辑等的利益
tripleee

1
此外,您的脚本不适用于包含空格或Shell元字符的路径。基本上,应该始终将变量放在双引号中,除非您特别要求Shell执行空格标记化和通配符扩展。有关详细信息,请访问stackoverflow.com/questions/10067266/…–
Tripleee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.