跨平台从tar删除dir的方法

时间:2018-12-18 04:00:30

标签: macos unix tar

我发现了这一点: https://www.cyberciti.biz/faq/unix-linux-appleosx-bsd-tar-remove-directory/

tar --delete -f file.tar 'path1/dir1'

,但这在MacOS上不起作用。我得到:

  

tar: Option --delete is not supported

我正在寻找适用于所有* nix口味的产品。有人知道这样做的好方法吗?也许我确实确实需要先提取文件,然后忽略该文件夹,然后重新压缩它?

1 个答案:

答案 0 :(得分:3)

简短回答

是的,如果您想要一种适用于多种* nix口味的解决方案,那么您将不得不;首先解压缩,忽略文件夹,然后重新打包。


解决方案:

我会做以下事情:

# Path to source .tar
src_tar=/the/path/to/your/tarfile.tar

# Path to dir in .tar that you want to delete.
rm_tar_dir=path1/dir1

# Create a temporary dir for extracting the .tar contents into.
tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'tar-tmpdir')

# Extract all contents from the source .tar to a temporary dir
tar zxf "$src_tar" -C "$tmp_dir"

# Delete the unwanted dir from temporary dir.
rm -rf "${tmp_dir:?}/${rm_tar_dir}"

# Create new .tar archive, overwriting the original source .tar
tar czf "$src_tar" -C "$tmp_dir" .

# Clean up
rm -rf "$tmp_dir"

为什么我建议上面显示的解决方案:

首先,(出于显而易见的原因)我无法测试并确认以上解决方案在所有 * nix口味上均能成功工作。其次,我不敢说其他原因是天真,因为(我确定您知道),这是一个很大的旧环境,即有很多版本,口味和变体。

基于以下发现/研究,我已经得出以上建议的解决方案。下表的支持/兼容性表中涵盖的 * nix 的风味远非详尽无遗。我已经从列出的here口味中选择了它们。

大多数选择的调味料是由免费提供(免费的BSD,免费的BSD等)志愿者小组开发的。幸运的是,这些 * nix口味的文档,手册页等已在线发布,它们一直是我决策的主要影响力。 IBM AIX和Sun的Solaris是例外,因为它们是专有的,但是这两个文件提供了一些文档,手册页等。


支持/兼容性表

  • tar --delete选项

    让我们首先了解对tar命令--delete选项的支持。正如您在下表中所看到的,它远没有得到广泛支持的:(,因此为什么似乎有必要采用更为冗长的解决方案-不幸的是,当需要跨平台时,我们不能使用oneliner。

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │ --delete    │  x  │  x   │  x   │  √  │       x      │   √   │    x    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    
  • 其他tar个选项

    以上提供的解决方案利用了多个tar选项,即; -z-x-f-c-C。如您在下表中所见,它们得到了广泛的支持。但是,值得注意的是,-z选项(用于通过gzip过滤归档文件)在IBM的AIX上不受支持,据我了解,该选项在大型机上使用-(所以,我的假设是:一个适合您的交易突破者。

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -z         │  x  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -x         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -f         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -c         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  -C         │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  --exclude  │  x  │  x   │  √   │  √  │      √       │   √   │    x    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

    tar --exclude选项

    请注意,在上表中,--exclude选项似乎也未得到广泛支持-出于这个原因,我们不在建议的解决方案中使用它。在解压缩.tar时,我会避免选择排除不需要的目录(即您要删除的目录)。因此,请避免执行以下操作:

    # Don't do this....
    
    # Extract all contents from the source .tar to a temporary dir,
    # and exclude the directory that you effectively want to delete.
    tar zxf "path/to/tarfile.tar" --exclude "path1/dir1" -C "path/to/tmpdir"
    

    您会发现,在建议的解决方案中,我们将所有内容解压缩(不排除在内),然后在重新打包之前使用rm -rf删除不需要的目录。


  • 解决方案使用的其他命令

    下表显示了建议的解决方案中使用的其余命令:

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  rm -rf     │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp     │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp -d  │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    ├─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mktemp -t  │  x  │  √   │  ?   │  √  │      √       │   √   │    √    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

    如您所见,我们很好地利用rm -rf,因为它得到了很好的支持。

    请注意mktemp ...

    mktemp以及-t-d选项似乎不太受支持。 (注意:我不确定Free BSD是否支持该功能-因此?指示器。)

    因此,尽管我建议的解决方案确实使用了mktemp,但您可能想改用mkdir -p,因为它得到了广泛的支持,如下表所示:

                  ┌─────┬──────┬──────┬─────┬──────────────┬───────┬─────────┐
                  │ IBM │ Open │ Free │ Net │ Darwin/MacOS │ Linux │ Sun     │
                  │ AIX │ BSD  │ BSD  │ BSD │     BSD      │  GNU  │ Solaris │
    ┌─────────────┼─────┼──────┼──────┼─────┼──────────────┼───────┼─────────┤
    │  mkdir -p   │  √  │  √   │  √   │  √  │      √       │   √   │    √    │
    └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
    

参考文献

以下参考文献用于总结建议的解决方案,并编译兼容性表:

  1. tar

  2. mktemp -d -t

  3. rm -rf

  4. mkdir -p

  5. 其他