Linux tar:添加当前目录中的所有文件和目录,包括.svn等

Linux tar:添加当前目录中的所有文件和目录,包括.svn等,linux,bash,design-patterns,tar,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 SLE

我尝试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(2.6.27.19)上使用bash)

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

cd ..
tar czf workspace.tar.gz workspace
假设您想要gzip的目录被称为workspace。

如果您真的不想在tarball中包含top目录(这通常是个坏主意):


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

ls $HOME/*

这将正确地排除特殊目录项
。在Bash中,您可以使用
*
明确包含点文件:

ls $HOME/* $HOME/.*

但这也包括
,所以这不是你想要的。我确信有某种方法可以使
*
与bash中的点文件匹配。

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

tar -czf workspace.tar.gz .
确实会更改当前目录,但为什么不将文件放在其他地方呢

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

您可以使用
--exclude
修复
表单:

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

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

不要在正在打包的目录中创建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..
进行物理更改目录。愚蠢的是,它不是默认的beh。)在我看来,这是一个令人困惑的问题,至少对于那些
cd..
从未有过其他意义的人来说是如此。)


讨论中的一条评论说:

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

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

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

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

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

    find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+
    
    find.-maxdepth 1
    将查找当前目录中的所有文件/目录/symlinks/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
    

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

    最低焦油量:

    tar --exclude=*.tar* -cf workspace.tar .
    
    管道连接到您选择的压缩器。此示例非常详细,使用xz进行最大压缩:

    tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz
    
    该解决方案在Ubuntu14.04和Windows7上的Cygwin上进行了测试。
    这是一个社区wiki答案,因此如果发现错误,请随意编辑。

    在要压缩的目录(当前目录)中,尝试以下操作:

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

    如果磁盘空间不是问题,那么这也是一件非常容易做到的事情:

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

    这里提供的大多数解决方案的问题是,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
    )。因此,如果您试图创建一个包,其中包含许多条目(目录和文件),则此解决方案将不起作用。

    需要采取以下步骤:

  • *
    替换为
    ,以包括隐藏文件
  • 要在同一目录中创建存档,可以使用
    --exclude=workspace.tar.gz
    排除存档本身
  • 要防止在尚未创建存档文件时,文件在读取时发生更改,请确保
    tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz
    
    tar -czf workspace.tar.gz . --exclude=./*.gz
    
    mkdir backup
    cp -r ./* backup
    tar -zcvf backup.tar.gz ./backup
    
    touch workspace.tar.gz
    tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
    
    tar -czf workspace.tar.gz `ls -A`
    
    tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)
    
    tar cf ../archive.tar .