ChatGPT解决这个技术问题 Extra ChatGPT

如何在所有子目录中压缩某些文件类型?

我想 tar 以及目录及其子目录中的所有 .php 和 .html 文件。如果我使用

tar -cf my_archive *

它会压缩所有我不想要的文件。如果我使用

tar -cf my_archive *.php *.html

它忽略子目录。我怎样才能使它递归地 tar 但只包含两种类型的文件?


D
DeeDee

find ./someDir -name "*.php" -o -name "*.html" | tar -cf my_archive -T -


@DeeDee 文件数量等有什么限制吗?
@DeeDee - 不,我的意思是你不需要括号!
@user1566515 可能存在一些文件系统限制或总体空间限制,这会对您的 tar 文件设置上限。这完全取决于您自己的系统。否则,管道基本上会即时创建 tar 文件,因此您不会受到文件数量或大小的限制。
谢谢! ...如何添加超过 2 个条件/类型的文件?
@gluuke 对每个新条件使用 -o -name [pattern]
S
Stabledog

如果您使用的是 bash 版本 >在 4.0 中,您可以利用 shopt -s globstar 来缩短工作时间:

shopt -s globstar; tar -czvf deploy.tar.gz **/Alice*.yml **/Bob*.json

这将从任何子目录添加以 Alice 开头的所有 .yml 文件,并从任何子目录添加以 Bob 开头的所有 .json 文件。


仅使用 tar 的唯一答案,IMO 的最佳答案。
尽管 glob '**' 对目录的印象,但此命令不会递归执行(任何子子文件夹)
@Eddie ** 应该可以工作。您的参数可能有所不同。还要检查您在命令行中传递的文件夹名称中是否有空格。如果没有,您可以粘贴您的实际命令吗?
'**' 在到达命令之前由 shell 评估,它只被视为 2 个独立的 *,它解析为 0 或字符,它没有跨越目录的递归功能 tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
@eddie 是的,它是由 shell 评估的,尽管 bash > 4.0有一个shopt -s globstar选项,所以答案是正确的,实际上是最好的
s
steampowered

一种方法是:

tar -cf my_archive.tar $( find -name "*.php" -or -name "*.html" )

但是,这种方法有一些注意事项:

如果有任何文件或目录中包含空格,它将失败,如果文件太多以至于最大命令行长度已满,它将失败。

解决这些问题的方法是将 find 命令的内容输出到文件中,然后使用“-T, --files-from FILE”选项来 tar。


1)“失败”是指将跳过带有空格的文件还是不会创建 tar 存档? 2)我有大约 10 万个文件。这是否超过了最大命令行长度?
1. 它将创建存档,但会报告丢失的文件。 2. 那会太长了,我想。鉴于此,您最好使用下面@DeeDee 建议的方法,它会很好地解决这些问题。
I
Ian Reinhart Geiser

这将处理带有空格的路径:

find ./ -type f -name "*.php" -o -name "*.html" -exec tar uvf myarchives.tar {} +

N
Noam Geffen

把它们放在一个文件中

find . \( -name "*.php" -o -name "*.html" \) -print > files.txt

然后将该文件用作 tar 的输入,根据您使用的 tar 版本使用 -I 或 -T

使用 h 复制符号链接

tar cfh my.tar -I files.txt 

d
dmitry_podyachev

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -I 'pigz -9' -cf target.tgz

对于多核或仅用于一个核心:

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -czf target.tgz


J
John Delaney

使用 zsh 很容易:

tar cvzf foo.tar.gz **/*.(php|html)

您是说-czvf吗?
- 对于 tar 是可选的。
W
Walter Tross

如果您想生成 压缩 tar 文件 (.tgz) 并希望避免文件名中出现 空格 问题:

find . \( -name \*.php -o -name \*.html \) -print0 | xargs -0 tar -cvzf my_archive.tgz

find-print0 “主要”使用 NULL (\0) 字节分隔输出文件名,因此可以很好地与 xargs-0 选项配合使用。

两个主 -name 周围的括号是必需的,因为否则 -print0 将只输出第二个 -name 的文件名(如果存在 -print-print0,则没有隐含的打印,并且这些只有如果对它们进行评估,则效果)。

如果您需要跳过一些文件名或目录(例如,如果您使用 Node.js,则为 node_modules 目录),请在前面添加一个或多个 -prune 主文件,如下所示:

find . -name skipThisName -prune -o \( -name \*.php -o -name \*.html \) -print0 | xargs -0 tar -cvzf my_archive.tgz