是否有一个简单的 shell 命令/脚本支持从存档中排除某些文件/文件夹?
我有一个需要与子目录一起归档的目录,其中包含许多我不需要备份的非常大的文件。
不完全解决方案:
tar --exclude=PATTERN
命令匹配给定模式并排除这些文件,但我需要特定文件 &要忽略的文件夹(完整文件路径),否则可能会排除有效文件。
我还可以使用 find 命令创建文件列表并排除我不想归档的文件并将列表传递给 tar,但这仅适用于少量文件。我有几万。
我开始认为唯一的解决方案是创建一个包含要排除的文件/文件夹列表的文件,然后使用 rsync 和 --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 .
--exclude
不必是第一个,但它必须位于源目录之前的某个位置(在 Cygwin 上使用 tar 1.29 进行了测试)。
您可以为 tar 设置多个排除选项
$ tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .
等会工作。确保确保将--exclude
置于源和目标项之前。
您可以使用 --exclude
排除目录作为 tar。
如果您想归档除 /usr
之外的所有内容,您可以使用:
tar -zcvf /all.tgz / --exclude=/usr
在你的情况下,也许像
tar -zcvf archive.tgz arc_dir --exclude=dir/ignore_this_dir
--exclude=dir/ignore_this_dir
也会匹配 any 子树!您最终会丢失您没想到会被排除在外的文件。
使用 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
老问题有很多答案,但我发现没有一个对我来说足够清楚,所以我想添加我的尝试。
如果你有以下结构
/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 的根目录(我在这里尝试了相对于 / 的完整路径,但我无法做到这一点)。
希望这会对某人有所帮助(以及我下次谷歌搜索时)
tar -czvf mysite.tar.gz mysite --exclude='./mysite/file3' --exclude='./mysite/folder3'
,这并没有排除任何东西。
您可以使用标准的“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
globstar
。检查 shopt -s globstar
。我认为它在大多数基于 unix 的操作系统上默认 关闭。来自 Bash 手册:“globstar: 如果设置,则在文件名扩展上下文中使用的模式 **
将匹配所有文件以及零个或多个目录和子目录。如果模式后跟'/',只有目录和子目录匹配。"
此排除模式处理文件名后缀(如 png 或 mp3)以及目录名(如 .git 和 node_modules)
tar --exclude={*.png,*.mp3,*.wav,.git,node_modules} -Jcf ${target_tarball} ${source_dirname}
我经历过这种情况,至少在我使用的 Cygwin 版本的 tar 中(“CYGWIN_NT-5.1 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin”在 Windows XP 家庭版上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,
我在其他地方发现了这个,所以我不会相信,但对于我的 mac 特定问题,它比上述任何解决方案都更有效(即使它已关闭):
tar zc --exclude __MACOSX --exclude .DS_Store -f <archive> <source(s)>
COPYFILE_DISABLE=1
,否则 you may get ._ files in your tarball
对于 Mac OSX,我必须这样做
tar -zcv --exclude='folder' -f theOutputTarFile.tar folderToTar
注意 --exclude=
后面的 -f
在阅读了不同版本的所有这些好的答案并为我自己解决了问题之后,我认为有非常小的细节非常重要,而且对于 GNU/Linux 的一般用途来说很少见,这些细节没有得到足够的重视,值得更多的评论。
因此,我不会尝试针对每种情况回答这个问题,而是尝试注册当事情不起作用时在哪里查看。
请务必注意:
选项的顺序很重要:将 --exclude 放在文件选项和要备份的目录之前与之后是不一样的。这至少对我来说是出乎意料的,因为根据我的经验,在 GNU/Linux 命令中,选项的顺序通常并不重要。不同的 tar 版本期望这个选项以不同的顺序:例如,@Andrew 的回答表明在 GNU tar v 1.26 和 1.28 中,排除项排在最后,而在我的情况下,对于 GNU tar 1.29,它是另一种方式。尾部斜线很重要:至少在 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/
引号无关紧要,无论有没有它们都有效。
我希望这对某人有用。
如果您尝试排除版本控制系统 (VCS) 文件,tar 已经支持两个有趣的选项! :)
选项:--exclude-vcs
此选项排除以下版本控制系统使用的文件和目录:CVS
、RCS
、SCCS
、SVN
、Arch
、Bazaar
、Mercurial
和 Darcs
。
从 1.32 版开始,以下文件被排除在外:
CVS/,以及它下面的一切
RCS/,以及它下面的一切
SCCS/,以及它下面的一切
.git/,以及它下面的所有内容
.gitignore
.gitmodules
.git 属性
.cvsignore
.svn/,以及它下面的一切
.arch-ids/,以及它下面的所有内容
{arch}/ 及其下的所有内容
=发布-ID
=元更新
=更新
.bzr
.bzrignore
.bzrtags
.hg
.hgignore
.hgrags
_darcs 选项:--exclude-vcs-ignores
选项:--exclude-vcs-ignores
当归档某个版本控制系统 (VCS) 下的目录时,从该 VCS 的忽略文件(例如 .cvsignore
、.gitignore
等)中读取排除模式通常很方便。此选项提供了这种可能性。
在归档目录之前,请查看它是否包含以下任何文件:cvsignore
、.gitignore
、.bzrignore
或 .hgignore
。如果是这样,请从这些文件中读取忽略模式。
这些模式的处理方式与相应的 VCS 处理它们的方式相同,即:
.cvsignore
包含仅适用于该文件所在目录的 shell 样式的通配模式。文件中不允许有评论。空行被忽略。
.gitignore
包含 shell 样式的 globbing 模式。适用于 .gitfile
所在的目录及其所有子目录。
任何以 #
开头的行都是注释。反斜杠转义注释字符。
.bzrignore
包含 shell globbing-patterns 和正则表达式(如果以 RE:
(16) 为前缀。模式会影响目录及其所有子目录。
任何以 #
开头的行都是注释。
.hgignore
包含 posix 正则表达式 (17)。 syntax: glob
行切换到 shell 通配模式。 syntax: regexp
行切换回来。注释以 #
开头。模式会影响目录及其所有子目录。
例子
tar -czv --exclude-vcs --exclude-vcs-ignores -f path/to/my-tar-file.tar.gz path/to/my/project/
对于那些对此有疑问的人,某些版本的 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 *
我想展示另一个我用来获得与之前提供的答案相同的结果的选项,我有一个类似的情况,我想将 android studio 项目全部备份到一个 tar 文件中以上传到 media fire,使用 du 命令要查找大文件,我发现我不需要一些目录,例如: build, linux e .dart_tools 使用 Charles_ma 的第一个答案,我对其进行了一些修改,以便能够从 my 的父目录运行命令安卓目录。
tar --exclude='*/build' --exclude='*/linux' --exclude='*/.dart_tool' -zcvf androidProjects.tar Android/
它就像一个魅力。
附言。抱歉,如果不允许这种答案,如果是这种情况,我将删除。
我同意 --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'
阅读此线程后,我在 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/*'
为避免在处理数万个文件时由于使用 find ... | xargs ...
而可能出现的 'xargs: Argument list too long'
错误,您可以使用 find ... -print0 | tar --null ...
将 find
的输出直接通过管道传送到 tar
。
# 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 -
xargs -n 1
是避免 xargs: Argument list too long
错误的另一种选择;)
您还可以根据需要使用“--exclude-tag”选项之一:
--排除标签=文件
--排除标记全部=文件
--exclude-tag-under=文件
将排除托管指定 FILE 的文件夹。
将 find 命令与 tar append (-r) 选项结合使用。这样,您可以在一个步骤中将文件添加到现有的 tar,而不是通过两次解决方案(创建文件列表,创建 tar)。
find /dir/dir -prune ... -o etc etc.... -exec tar rvf ~/tarfile.tar {} \;
您可以使用 cpio(1) 创建 tar 文件。 cpio 将文件归档到标准输入,因此,如果您已经确定了要用于选择归档文件的 find 命令,请将其通过管道传输到 cpio 以创建 tar 文件:
find ... | cpio -o -H ustar | gzip -c > archive.tar.gz
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
中的命令大致相同。
tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt
-X 表示包含必须从备份中排除的文件名列表的文件。例如,您可以在此文件中指定 *~ 以在备份中不包含任何以 ~ 结尾的文件名。
tar cXvfJ EXCLUDE-LIST ARCHIVE.tar.xz SOURCE-FOLDER
一探究竟
tar cvpzf zip_folder.tgz . --exclude=./public --exclude=./tmp --exclude=./log --exclude=fileName
成功案例: 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
失败案例:
如果给当前路径目录进行备份并忽略完整路径,则无法使用 tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz --exclude='/opt/ABC/csv/' --exclude='/ opt/ABC/log/' ABC
注意:在备份目录之前/之后提及排除是可以的。
最好的办法是通过 xargs 将 find 与 tar 一起使用(处理大量参数)。例如:
find / -print0 | xargs -0 tar cjf tarfile.tar.bz2
find / -print0 | tar -T- --null --no-recursive -cjf tarfile.tar.bz2
xargs
时,应该使用 tar r
选项而不是 c
,因为当 find
实际找到大量结果时,xargs 将拆分这些结果(基于本地命令行参数限制)成块并在每个部分上调用 tar 。这将生成一个包含 xargs
返回的最后一个块的存档,而不是 find
命令找到的所有结果。
可能多余的答案,但因为我发现它很有用,这里是:
虽然是 FreeBSD 根目录(即使用 csh),但我想将整个根文件系统复制到 /mnt 但没有 /usr 和(显然)/mnt。这是有效的(我在/):
tar --exclude ./usr --exclude ./mnt --create --file - . (cd /mnt && tar xvd -)
我的全部观点是,有必要(通过放置 ./)指定 tar 排除的目录,其中较大目录的一部分被复制。
我的 €0.02
我没有运气让 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)
zip
不会打包空目录,但 tar
会!
我想在本地主机上有新的前端版本(角度文件夹)。另外,在我的情况下, 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/
似乎不可能排除具有绝对路径的目录。一旦任何路径是绝对的(源或/和排除),排除命令将不起作用。这是我尝试了所有可能的组合后的经验。
以下 bash 脚本应该可以解决问题。它使用 Marcus Sundman 给出的答案 here。
#!/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 '列表中的一个条目'。斜杠 () 是 ' 标记的转义字符。
tar -zcv --exclude='file1' --exclude='patter*' --exclude='file2' -f /backup/filename.tgz .
注意-f
标志需要在 tar 文件之前看到:superuser.com/a/559341/415047