是否可以只压缩子目录而不包括文件夹中的其他文件?

是否可以只压缩子目录而不包括文件夹中的其他文件?

例如,假设A/B/C是主目录。在该C目录下,我将有子目录和文件。但我只想压缩具有自己名称的目录,如下所示

如果 c 下的目录是 Test1 Test2 - 我希望它们为 Test1.tar Test2.tar

这是在 Linux 机器上。

答案1

您可以告诉tar不要递归到其参数,然后使用find它提供每个目录作为参数。所以,像这样:

find . -type d -print0 | xargs -0 tar --no-recursion -cf your_tree.tar

-print0-0为了避免名称中包含空格和其他特殊字符的目录出现问题。

正如下面的评论所指出的,如果您有很多目录,那么命令行将变得太大并且tar最终会被多次调用。在这种情况下,您可以使用以下方式读取参数--files-from

find . -type d -print0 | tar --null --no-recursion --files-from - -cf your_tree.tar

编辑:

上面的内容是在 OP 澄清他们想要顶级目录中的一组 tar 文件之前编写的。我认为上述技术仍然可以用来实现这一目标。例如:

$ mkdir -vp tree/a/b/c tree/foo/bar/baz                                                                                 
mkdir: created directory ‘tree’
mkdir: created directory ‘tree/a’
mkdir: created directory ‘tree/a/b’
mkdir: created directory ‘tree/a/b/c’
mkdir: created directory ‘tree/foo’
mkdir: created directory ‘tree/foo/bar’
mkdir: created directory ‘tree/foo/bar/baz’
$ touch tree/foo/an_unwanted_file
$ cd tree
/var/tmp/tree
$ for dir in $(find . -maxdepth 1 -type d); do if [ "$dir" != "." ]; then find "$dir" -type d -print0 | tar --null --no-recursion --files-from - -cvf "${dir}.tar"; fi; done
./a/
./a/b/
./a/b/c/
./foo/
./foo/bar/
./foo/bar/baz/
$ tar tvf foo.tar                                                                                                       
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/bar/
drwxr-xr-x andy/andy         0 2018-11-29 12:30 ./foo/bar/baz/
$ tree
.
├── a
│   └── b
│       └── c
├── a.tar
├── foo
│   ├── an_unwanted_file
│   └── bar
│       └── baz
└── foo.tar

答案2

for dir in A/B/C/*/; do
    name=$(basename "$dir")
    tar -cv -f "$name.tar" -C A/B/C "$name"
done

这将为 下的每个单独(非隐藏)子目录创建一个存档A/B/C。存档将在当前目录中创建。

-C选项tar设置以下文件的工作目录 ( $name)。

您可以使用-C "$(dirname "$dir")"代替-C A/B/C稍微更通用的代码。


C在子目录下创建档案

( cd A/B/C &&
  for dir in */; do
      tar -cv -f "${dir%/}.tar" "$dir"
  done )

整个命令周围的子 shell 可防止在 shell/脚本的其余部分中更改工作目录,并${dir%/}删除 中值末尾的尾部斜杠$dir

不幸的是,该-C选项不会影响 指定的存档文件的工作目录-f,否则我们可以只移动-C该选项之前的位-f

或者,作为第一个循环的变体:

for dir in A/B/C/*/; do
    name=$( basename "$dir" )
    ( cd "$( dirname "$dir" )" && tar -cv -f "$name.tar" "$name" )
done

答案3

我建议使用(我是最古老的免费 tar 实现star的作者):star

star cf file.tar -find . -type d

这适用于 tar 文件中任意数量的名称,因为star使用libfind-

相关内容