g
我正在使用此命令来存档以 Java 代码命名的目录:
tar czf /a/b/c.tar.gz /e/f/g
c.tar.gz
创建tar 文件时,我会查找完整路径e/f/g
,然后查找其中g
文件夹的所有文件。但我只想g
在打开压缩档案时查看文件夹下的文件。如何删除/e/f/
.tar.gz 文件中的文件夹?
答案1
答案2
这个问题是很久以前提出的,但我仍然无法轻松地找到使用相对路径添加具有特定搜索条件的文件和文件夹的答案。
以下内容涵盖的主题比所问内容更广泛。因此,我正在写下我根据研究得出的解决方案。
假设您的$input_dir
变量指向您感兴趣的目录,并且您希望将所有*.txt
文件打包并压缩(使用 gzip)到~/my_txt.tar.gz
。要创建 gzip 压缩的 tarball,且 tar 中不存储路径(相对路径),请使用以下命令:
find "$input_dir" -maxdepth 1 -type f -name "*.txt" -printf "%P\0" | tar --null --create --remove-files --gzip --file="$HOME/my_txt.tar.gz" --directory="$input_dir" --files-from=-
让我们分解一下:
"$input_dir"
:起始点目录。将其更改为您喜欢的任何内容。maxdepth 1
:仅查找该目录的根目录。如果要搜索所有或不同级别,可以删除或修改它。-type f
:仅搜索文件-name "*.txt"
:匹配 *.txt 条件-printf "%P"
:输出相对路径(手册页:“文件的名称以及找到该文件的起点的名称已被删除”)。-printf "%P\0"
: null 终止相对路径输出| tar
:将输出通过管道传输到下一个命令,此处为 tar--null
: 指示后续--files-from
选项读取以空字符结尾的名称。请记住,我们要求find
创建以空字符结尾 (\0
) 的输出,而不是以常规\n
结尾的输出。这是为了覆盖所有可能带有空格或其他特殊字符的文件名。--create
:创建 tar 文件。等于-c
。--remove-files
:我使用此选项在将文件添加到 tarball 后将其删除。您可以将其删除。--gzip
:gzip 压缩包。等于-z
。--file="$HOME/my_txt.tar.gz"
:输出 gzip 压缩包文件。等于-f "$HOME/my_txt.tar.gz"
--directory="$input_dir"
:这意味着tar
现在更改到此目录。现在它将在此目录中查找传递的文件名(请记住,我们已将文件名的相对路径设为此文件夹)。等于-C "$input_dir"
。--files-from=/dev/stdin
:其一般形式为--files-from=FILE
。此选项与选项一起--null
指示tar
中的名称FILE
以 ASCII NULL 字符分隔,而不是换行符 (\n
)。我们还说 是FILE
(stdin
从find
直接通过管道传输到tar
而不是从FILE
磁盘上的 读取)。等于-T -
。
以上部分可以改为一个字符选项,并可以组合。
find "$input_dir" -maxdepth 1 -type f -name "*.txt" -printf "%P\0" | tar --null --remove-files -czf "$HOME/my_txt.tar.gz" -C "$input_dir" -T -
-t
您可以使用或选项检查文件列表--list
:
tar -tf "$HOME/my_txt.tar.gz"
现在将文件提取到 $output_dir 目录(存在),使用以下命令:
tar -xvzf "$HOME/my_txt.tar.gz" -C "$output_dir"
该v
选项很详细,您也可以在创建 tarball 期间添加它。
答案3
slhck 答案不允许过滤我们想要的文件并包含整个目录,并且 shell 通配符不适用于此目录选项(请参阅此处描述的此问题:如何通过“更改目录”选项使 tar 通配符起作用)。
shaheen g 的回答很棒,但空字节阻止我在编程语言中使用该命令,因为字符串中禁止使用空字节。因此,我对其进行了调整,以便在不需要处理带有空格的文件名时不使用空字节,答案这里。
tar -czf /a/b/c.tar.gz -C /e/f/g $(find /e/f/g -maxdepth 1 -type f -name "*.txt" -printf "%f\n")
或者
find /e/f/g -maxdepth 1 -type f -name "*.txt" -printf "%f\n" | tar -czf /a/b/c.tar.gz -C /e/f/g -T -