关于Linux:shell命令到tar目录,不包括某些文件/文件夹

Shell command to tar directory excluding certain files/folders

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

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

不完全解决方案:

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

我也可以使用find命令创建一个文件列表,排除那些我不想归档的文件,并将列表传递给tar,但这只适用于少量的文件。我有数万。

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

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

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

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


对于tar,您可以有多个排除选项,因此

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

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


对于tar,可以排除带有--exclude的目录。

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

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

在你的情况下,也许

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


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

排除使用多个模式的文件

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

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

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

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

1
tar -czf backup.tar.gz --exclude-tag-all=exclude.tag /path/to/backup


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

如果你有以下结构

1
/home/ftp/mysite/

使用以下文件/文件夹

1
2
3
4
5
6
/home/ftp/mysite/file1
/home/ftp/mysite/file2
/home/ftp/mysite/file3
/home/ftp/mysite/folder1
/home/ftp/mysite/folder2
/home/ftp/mysite/folder3

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

我们使用格式

1
tar -czvf <name of tar file> <what to tar>

其中c=create、z=zip和v=verbose(在输入文件时可以看到这些文件,这对于确保没有添加排除的文件很有用)。F=文件。

所以,我的命令应该是这样的

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

请注意,排除的文件/文件夹相对于您的tar的根目录(我尝试了相对于/的完整路径,但无法使其工作)。

希望这能帮助别人(下次我用谷歌搜索时也是如此)


我经历过,至少在我使用的Cygwin版tar(在Windows XP Home Edition SP3机器上为"Cygwin_nt-5.1 1 1.7.17(0.262/5/3)2012-10-19 14:39 i686 cygwin")中,选项顺序很重要。

当这个建筑为我工作时:

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

那个不起作用:

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

虽然tar --help揭示了以下情况:

1
tar [OPTION...] [FILE]

所以,第二个命令也应该有效,但显然情况并非如此……

最佳RGDS,


您可以使用标准的"ant notation"排除相对目录。这对我有效,不包括任何.git或节点_模块目录。

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

myinputfile.txt包含:

/DEV2/Java/开发2/javascript


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

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

我在其他地方发现了这个问题,所以我不想赊账,但它比上面针对我的Mac特定问题的任何解决方案都有效(即使这是关闭的):

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


对于那些对它有问题的人,一些版本的tar只能在exclude值中没有"./"的情况下正常工作。

1
Tar --version

tar (GNU tar) 1.27.1

有效的命令语法:

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

这是行不通的:

1
2
3
4
5
6
7
8
$ 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 *


对于Mac OSX,我必须这么做

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

注意在--exclude=之后的-f


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

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

一句对我没有立即发现的副作用的警告:在本例中排除"filea"将递归搜索"filea"!

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

1
2
3
4
5
data.txt
config.txt
--+dirA
  |  data.txt
  |  config.docx
  • 如果使用--exclude='data.txt',存档将不包含data.txt文件。如果存档第三方库(如节点模块目录),这可能会导致意外结果。

  • 为了避免这个问题,确保给出完整的路径,如--exclude='./dirA/data.txt'


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

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

为了避免在处理数万个文件时使用find ... | xargs ...可能导致的'xargs: Argument list too long'错误,可以使用find ... -print0 | tar --null ...find的输出直接传输到tar上。

1
2
3
4
5
6
# 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 -


在阅读了这篇文章之后,我对RHEL5做了一些测试,下面是我对ABC目录的调整结果:

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

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

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

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


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

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

将排除承载指定文件的文件夹。


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

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

gnu tar v 1.26--exclude需要在存档文件和备份目录参数之后出现,应该没有前导或尾随斜杠,并且不希望使用引号(单引号或双引号)。所以相对于要备份的父目录,它是:

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


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

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


您最好的选择是通过xargs使用find with tar(处理大量参数)。例如:

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


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

当一个freebsd根(即使用csh)时,我想将整个根文件系统复制到/mnt,但不使用/usr和(显然是)/mnt。这是有效的(我在/)方法:

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

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

我的0.02欧元


过来看

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

我没有运气把tar排除在几个级别的5G子目录之外。最后,我只使用了unix-zip命令。这对我来说容易多了。

所以对于这个来自原始帖子的特殊例子(tar--exclude='./folder'--exclude='./upload/folder2'-zcvf/backup/filename.tgz。)

相当于:

zip -r /backup/filename.zip . -x upload/folder/**\* upload/folder2/**\*

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


下面的bash脚本应该可以做到这一点。它使用了马库斯·桑德曼给出的答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/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更改为要排除的任何其他通用扩展名、文件名或regex,这仍然有效。

编辑

只需添加一点解释;find会生成与所选regex匹配的文件列表(在本例中为*.cc)。此列表通过xargs传递给echo命令。此打印--排除"列表中的一个条目"。斜线()是"标记"的转义字符。