繁体   English   中英

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

[英]Shell command to tar directory excluding certain files/folders

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

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

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

等会起作用。 确保--exclude源和目标项目之前

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

如果要存档除/usr之外的所有内容,可以使用:

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

在你的情况下,也许像

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

使用 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 的根目录(我在这里尝试了相对于 / 的完整路径,但我无法使其工作)。

希望这会帮助某人(还有我下次谷歌搜索时)

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

这个排除模式处理像 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" on Windows XP Home Edition 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)>

对于 Mac OSX 我必须做

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

注意--exclude=后面的-f

对于那些遇到问题的人来说,某些版本的 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 *

在阅读了所有这些不同版本的好答案并为我自己解决了问题之后,我认为有一些非常重要的小细节,对于 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 伸展上的 GNU tar 1.29,有效的命令是

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

引号无关紧要,无论有没有它们都可以使用。

我希望这对某人有用。

如果您试图排除版本控制系统 (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

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

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

模式的处理方式与相应的 VCS 处理方式相同,即:

.cvsignore

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

.gitignore

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

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

.bzrignore

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

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

.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/

我同意 --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'

阅读完这篇文章后,我对 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 ... | xargs ... find ... | xargs ...文件的处理时,几万,你可以管的输出find直接tar使用find ... -print0 | tar --null ... 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-tag”选项之一:

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

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

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

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

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

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

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

find ... | cpio -o -H ustar | gzip -c > archive.tar.gz
tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt

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

排除绝对路径的目录似乎是不可能的。 一旦任何路径是绝对路径(源或/和排除),排除命令将不起作用。 这是我尝试所有可能组合后的经验。

一探究竟

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

成功案例: 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. 如果让当前路径目录进行备份并忽略完整路径,则将无法正常工作

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

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

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

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

它就像一个魅力。

附言。 对不起,如果不允许这种答案,如果是这种情况我会删除。

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

虽然是 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 /backup/filename.zip 。 -x 上传/文件夹/**\\* 上传/文件夹 2/**\\*

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

我想在本地主机上拥有新的前端版本(角度文件夹)。 另外,在我的情况下,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/

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

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

以下 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 'one entry from the list'。 斜线 () 是 ' 标记的转义字符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM