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

发布于 2024-09-17 17:36:22 字数 431 浏览 10 评论 0 原文

我尝试 tar.gz 目录并使用

tar -czf workspace.tar.gz *

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

我尝试使用

tar -czfworkspace.tar.gz . 来代替,但随后我收到错误,因为 '.' 在读取时已更改:

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

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

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

I try to tar.gz a directory and use

tar -czf workspace.tar.gz *

The resulting tar includes .svn directories in subdirs but NOT in the current directory (as * gets expanded to only 'visible' files before it is passed to tar

I tried to

tar -czf workspace.tar.gz . instead but then I am getting an error because '.' has changed while reading:

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

Is there a trick so that * matches all files (including dot-prefixed) in a directory?

(using bash on Linux SLES-11 (2.6.27.19)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

你的心境我的脸 2024-09-24 17:36:22

不要在要打包的目录中创建 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 中。

Don't create the tar file in the directory you are packing up:

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

does the trick, except it will extract the files all over the current directory when you unpack. Better to do:

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

or, if you don't know the name of the directory you were in:

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

(This assumes that you didn't follow symlinks to get to where you are and that the shell doesn't try to second guess you by jumping backwards through a symlink - bash is not trustworthy in this respect. If you have to worry about that, use cd -P .. to do a physical change directory. Stupid that it is not the default behaviour in my view - confusing, at least, for those for whom cd .. never had any alternative meaning.)


One comment in the discussion says:

I [...] need to exclude the top directory and I [...] need to place the tar in the base directory.

The first part of the comment does not make much sense - if the tar file contains the current directory, it won't be created when you extract file from that archive because, by definition, the current directory already exists (except in very weird circumstances).

The second part of the comment can be dealt with in one of two ways:

  1. Either: create the file somewhere else - /tmp is one possible location - and then move it back to the original location after it is complete.
  2. Or: if you are using GNU Tar, use the --exclude=workspace.tar.gz option. The string after the = is a pattern - the example is the simplest pattern - an exact match. You might need to specify --exclude=./workspace.tar.gz if you are working in the current directory contrary to recommendations; you might need to specify --exclude=workspace/workspace.tar.gz if you are working up one level as suggested. If you have multiple tar files to exclude, use '*', as in --exclude=./*.gz.
私野 2024-09-24 17:36:22

需要执行几个步骤:

  1. * 替换为 . 以包含隐藏文件。
  2. 要在同一目录中创建存档,可以使用 --exclude=workspace.tar.gz 来排除存档本身。
  3. 为了防止在尚未创建存档时出现 tar: .: filechanged as we read it 错误,请确保它存在(例如使用 touch),这样 --exclude 与存档文件名匹配。 (它与文件不存在不匹配)

将其组合成以下脚本:

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

There are a couple of steps to take:

  1. Replace * by . to include hidden files as well.
  2. To create the archive in the same directory a --exclude=workspace.tar.gz can be used to exclude the archive itself.
  3. To prevent the tar: .: file changed as we read it error when the archive is not yet created, make sure it exists (e.g. using touch), so the --exclude matches with the archive filename. (It does not match it the file does not exists)

Combined this results in the following script:

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
jJeQQOZ5 2024-09-24 17:36:22

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

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

If you really don't want to include top directory in the tarball (and that's generally bad idea):

tar czf workspace.tar.gz -C /path/to/workspace .
み零 2024-09-24 17:36:22

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

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

in directory want to compress (current directory) try this :

tar -czf workspace.tar.gz . --exclude=./*.gz
时光清浅 2024-09-24 17:36:22

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

cd ..
tar czf workspace.tar.gz workspace

假设您想要 gzip 的目录称为工作区。

You can include the hidden directories by going back a directory and doing:

cd ..
tar czf workspace.tar.gz workspace

Assuming the directory you wanted to gzip was called workspace.

影子的影子 2024-09-24 17:36:22

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

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

You can fix the . form by using --exclude:

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .
星軌x 2024-09-24 17:36:22

还有另一种解决方案,假设文件夹中的项目数量并不大,并且假设所有名称都不包含 shell 解释为分隔符(空格)的字符:

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

(ls -A 打印普通文件和隐藏文件,但不打印“.”和“..”就像ls -a一样。)

Yet another solution, assuming the number of items in the folder is not huge and assuming all names do not contain characters the shell interprets as delimiters (whitespace):

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

(ls -A prints normal and hidden files but not "." and ".." as ls -a does.)

相权↑美人 2024-09-24 17:36:22

更新:我添加了对OP评论的修复。

tar -czf workspace.tar.gz .

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

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

Update: I added a fix for the OP's comment.

tar -czf workspace.tar.gz .

will indeed change the current directory, but why not place the file somewhere else?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update
暗喜 2024-09-24 17:36:22

实际上问题出在压缩选项上。技巧是将 tar 结果通过管道传输到压缩器,而不是使用内置选项。顺便说一句,这也可以为您提供更好的压缩,因为您可以设置额外的压缩选项。

最小焦油:

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

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

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

解决方案已在 Windows 7 上的 Ubuntu 14.04 和 Cygwin 上进行了测试。
这是社区 wiki 的答案,因此如果您发现错误,请随时进行编辑。

Actually the problem is with the compression options. The trick is the pipe the tar result to a compressor instead of using the built-in options. Incidentally that can also give you better compression, since you can set extra compresion options.

Minimal tar:

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

Pipe to a compressor of your choice. This example is verbose and uses xz with maximum compression:

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

Solution was tested on Ubuntu 14.04 and Cygwin on Windows 7.
It's a community wiki answer, so feel free to edit if you spot a mistake.

冷情 2024-09-24 17:36:22

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

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

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

Had a similar situation myself. I think it is best to create the tar elsewhere and then use -C to tell tar the base directory for the compressed files. Example:

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

This way there is no need to exclude your own tarfile. As noted in other comments, -A will list hidden files.

帅哥哥的热头脑 2024-09-24 17:36:22

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

ls $HOME/*

并且

ls $HOME/*(D)

这正确地排除了特殊目录条目 ...。在 Bash 中,您可以使用 .* 显式包含点文件:

ls $HOME/* $HOME/.*

但这也包括 ...,所以它不是您原来的样子寻找。我确信也有某种方法可以使 * 匹配 bash 中的点文件。

A good question. In ZSH you can use the globbing modifier (D), which stands for "dotfiles". Compare:

ls $HOME/*

and

ls $HOME/*(D)

This correctly excludes the special directory entries . and ... In Bash you can use .* to include the dotfiles explicitly:

ls $HOME/* $HOME/.*

But that includes . and .. as well, so it's not what you were looking for. I'm sure there's some way to make * match dotfiles in bash, too.

一花一树开 2024-09-24 17:36:22

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

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

如果当前目录中已有 my.tar.gz,您可能需要将其 grep 出来:

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

请注意 xargs 有一定的限制(请参阅xargs --show-limits)。因此,如果您尝试创建一个包,该包在您尝试压缩的目录上包含大量条目(目录和文件),则此解决方案将不起作用。

The problem with the most solutions provided here is that tar contains ./ at the begging of every entry. So this results in having . directory when opening it through GUI compressor. So what I ended up doing is:

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

If you already have my.tar.gz in current directory you may want to grep this out:

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

Be aware of that xargs has certain limit (see xargs --show-limits). So this solution would not work if you are trying to create a package which has lots of entries (directories and files) on a directory which you are trying to tar.

荒岛晴空 2024-09-24 17:36:22

10 年后,您有了 tar 的替代方案,如 Git 2.30(2021 年第一季度)所示,它使用“git 存档"(man) 生成发布 tarball
而不是 tar。
(您不需要 Git 2.30 来应用该替代方案)

请参阅 提交 4813277 (11 2020 年 10 月),以及提交 93e7031(2020 年 10 月 10 日) https://github.com/rscharfe" rel="nofollow noreferrer">René Scharfe (rscharfe)。
(由 Junio C Hamano -- gitster -- 合并于 提交 63e5273,2020 年 10 月 27 日)

Makefile:使用 git init/add/提交/归档 dist-doc

签字人:René Scharfe

通过使用 git(man< /a>) 命令而不是 tar。
这为存档条目提供了与二进制文件的 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

这最初是提议的,因为,如 此处解释,某些异国情调的平台可能有一个旧的 tar 发行版,缺少选项。

10 years later, you have an alternative to tar, illustrated with Git 2.30 (Q1 2021), which uses "git archive"(man) to produce the release tarball
instead of tar.
(You don't need Git 2.30 to apply that alternative)

See commit 4813277 (11 Oct 2020), and commit 93e7031 (10 Oct 2020) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit 63e5273, 27 Oct 2020)

Makefile: use git init/add/commit/archive for dist-doc

Signed-off-by: René Scharfe

Reduce the dependency on external tools by generating the distribution archives for HTML documentation and manpages using git(man) commands instead of tar.
This gives the archive entries the same meta data as those in the dist archive for binaries.

So instead of:

tar cf ../archive.tar .

You can do using Git only:

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

That was initially proposed because, as explained here, some exotic platform might have an old tar distribution with lacking options.

甚是思念 2024-09-24 17:36:22
tar -czf workspace.tar.gz .??* *

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

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

Specifying .??* will include "dot" files and directories that have at least 2 characters after the dot. The down side is it will not include files/directories with a single character after the dot, such as .a, if there are any.

宁愿没拥抱 2024-09-24 17:36:22

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

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

find 。 -maxdepth 1 将查找当前目录中的所有文件/目录/符号链接/等,并运行-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

Using find is probably the easiest way:

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

find . -maxdepth 1 will find all files/directories/symlinks/etc in the current directory and run the command specified by -exec. The {} in the command means file list goes here and \+ means that the command will be run as:

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

instead of

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3
拧巴小姐 2024-09-24 17:36:22

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

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

If disk space space is not an issue, this could also be a very easy thing to do:

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文