tar:添加当前目录INCLUDING .svn中的所有文件和目录,依此类推

时间:2010-09-06 13:23:12

标签: linux bash design-patterns tar

我尝试tar.gz目录并使用

tar -czf workspace.tar.gz *

生成的tar包含子目录中的.svn目录,但不包含在当前目录中(因为*在传递给tar之前只扩展为“可见”文件

我试过

tar -czf workspace.tar.gz .但是我得到了一个错误,因为'。'在阅读时发生了变化:

tar: ./workspace.tar.gz: file changed as we read it

是否有一个技巧,以便*匹配目录中的所有文件(包括点前缀)?

(在Linux SLES-11上使用bash(2.6.27.19)

16 个答案:

答案 0 :(得分:57)

不要在要打包的目录中创建tar文件:

tar -czf /tmp/workspace.tar.gz .

可以解决这个问题,除非它在解压缩时会提取当前目录中的文件。更好:

cd ..
tar -czf workspace.tar.gz workspace

或者,如果您不知道您所在目录的名称:

base=$(basename $PWD)
cd ..
tar -czf $base.tar.gz $base

(这假设你没有按照符号链接到达你的位置,并且shell不会试图通过向后跳过符号链接来猜测你 - bash在这方面不值得信任。如果您不得不担心这一点,请使用cd -P ..进行物理更改目录。愚蠢的说,这不是我视图中的默认行为 - 至少对那些cd ..从未有过的人感到困惑替代意义。)


讨论中的一条评论说:

  

我[...]需要排除顶级目录,我需要将tar放在基目录中。

注释的第一部分没有多大意义 - 如果tar文件包含当前目录,则从该存档中提取文件时不会创建它,因为根据定义,当前目录已存在(除了非常奇怪的情况)。

评论的第二部分可以通过以下两种方式之一来处理:

  1. 或者:在其他地方创建文件 - /tmp是一个可能的位置 - 然后在完成后将其移回原始位置。
  2. 或者:如果您使用的是GNU Tar,请使用--exclude=workspace.tar.gz选项。 =之后的字符串是一个模式 - 示例是最简单的模式 - 完全匹配。如果您在当前目录中工作而违反建议,则可能需要指定--exclude=./workspace.tar.gz;如果您按照建议操作一个级别,则可能需要指定--exclude=workspace/workspace.tar.gz。如果要排除多个tar文件,请使用“*”,与--exclude=./*.gz中一样。

答案 1 :(得分:42)

如果确实不希望在tarball中包含top目录(这通常是个坏主意):

tar czf workspace.tar.gz -C /path/to/workspace .

答案 2 :(得分:25)

需要采取以下几个步骤:

  1. *替换为.以包含隐藏文件。
  2. 要在同一目录中创建存档,可以使用--exclude=workspace.tar.gz排除存档本身。
  3. 要防止在尚未创建存档时出现tar: .: file changed as we read it错误,请确保它存在(例如,使用touch),以便 - exclude 与存档匹配文件名。 (它不匹配文件不存在)
  4. 将此结果合并到以下脚本中:

    touch workspace.tar.gz
    tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
    

答案 3 :(得分:17)

目录中的

想要压缩(当前目录)试试这个:

tar -czf workspace.tar.gz . --exclude=./*.gz

答案 4 :(得分:7)

您可以通过返回目录并执行以下操作来包含隐藏目录:

cd ..
tar -czf workspace.tar.gz workspace

假设您想要gzip的目录名为workspace。

答案 5 :(得分:6)

您可以使用.修正--exclude表单:

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

答案 6 :(得分:4)

更新:我为OP的评论添加了修复程序。

tar -czf workspace.tar.gz .

确实会更改当前目录,但为什么不将文件放在其他位置?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update

答案 7 :(得分:4)

实际上问题在于压缩选项。诀窍是将tar结果输出到压缩器而不是使用内置选项。顺便提一下,这也可以为您提供更好的压缩,因为您可以设置额外的压缩选项。

最小焦油:

tar --exclude=*.tar* -cf workspace.tar .

管道到您选择的压缩机。此示例详细,并使用xz进行最大压缩:

tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz

在Windows 7上的Ubuntu 14.04和Cygwin上测试了解决方案。 这是社区维基的答案,如果发现错误,请随时编辑。

答案 8 :(得分:1)

一个好问题。在ZSH中,您可以使用globbing修饰符(D),它代表“dotfiles”。比较:

ls $HOME/*

ls $HOME/*(D)

这正确排除了特殊目录条目...。在Bash中,您可以使用.*明确地包含dotfiles:

ls $HOME/* $HOME/.*

但这包括...,所以它不是你想要的。我确信有一些方法可以在bash中使*匹配dotfiles。

答案 9 :(得分:0)

tar -czf workspace.tar.gz .??* *

指定.??*将包含点后面至少包含2个字符的“点”文件和目录。不利的一面是,它不包括点后的单个字符的文件/目录,例如.a,如果有的话。

答案 10 :(得分:0)

如果磁盘空间不是问题,那么这也很容易:

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup

答案 11 :(得分:0)

这里提供的大多数解决方案的问题是tar在每个条目的开头都包含./。因此,当通过GUI压缩器打开时,这会导致.目录。所以我最终做的是:

ls -1A | xargs -d "\n" tar cfz my.tar.gz

如果你当前目录中已经有my.tar.gz,你可能想要解决这个问题:

ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz

请注意 xargs有一定限制(请参阅xargs --show-limits)。因此,如果您尝试在要尝试tar的目录上创建包含大量条目(目录和文件)的包,则此解决方案将无效。

答案 12 :(得分:0)

另一种解决方案,假设文件夹中的项目数量不是很大:

tar -czf workspace.tar.gz `ls -A`

ls -A打印正常和隐藏文件,但不打印"。"和" .."如ls -a那样。)

答案 13 :(得分:0)

我自己也有类似的情况。我认为最好在别处创建tar,然后使用-C告诉tar压缩文件的基目录。例如:

tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)

这样就不需要排除自己的tarfile了。如其他评论中所述,-A将列出隐藏文件。

答案 14 :(得分:0)

10年后,您可以用tar替代,如Git 2.30(Q1 2021)所示,它使用“ git archiveman产生释放包 代替的焦油。
(您无需Git 2.30即可应用该替代方法)

请参见commit 4813277前的commit 93e7031(2020年10月11日)和René Scharfe (rscharfe)(2020年10月10日)。
(由Junio C Hamano -- gitster --commit 63e5273中合并,2020年10月27日)

Makefile:将git init / add / commit / archive用于dist-doc

签名人:RenéScharfe

通过使用git man命令而不是tar生成HTML文档和联机帮助页的发行档案来减少对外部工具的依赖。 这样,存档条目将与dist存档的二进制文件具有相同的元数据。

所以代替:

tar cf ../archive.tar .

您只能使用Git:

git -C workspace init
git -C workspace add .
git -C workspace commit -m workspace
git -C workspace archive --format=tar --prefix=./ HEAD^{tree} > workspace.tar
rm -Rf workspace/.git

最初提出这个建议是因为,像explained here一样,某些奇特的平台可能具有较旧的tar发行版,缺少选项。

答案 15 :(得分:-1)

使用find可能是最简单的方法:

find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+

find . -maxdepth 1将在当前目录中找到所有文件/目录/符号链接/ etc,并运行-exec指定的命令。命令中的{}表示文件列表在此处\+表示该命令将按以下方式运行:

tar zcvf workspace.tar.gz .file1 .file2 .dir3

而不是

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3