代码之家  ›  专栏  ›  技术社区  ›  Alexander Mills

跨平台方式从tarball中移除dir

  •  2
  • Alexander Mills  · 技术社区  · 6 年前

    我发现这一点: 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

    我想买些适合所有尼克斯口味的。有人知道怎么做吗?也许我真的需要先提取并忽略文件夹,然后重新tarball它?

    1 回复  |  直到 6 年前
        1
  •  3
  •   RobC Manuel Gonzalez    6 年前

    简短回答

    是的,如果你想要一个在很多方面都有效的解决方案* 尼克斯香精 然后你就必须这样做:首先提取,忽略文件夹,然后重新涂焦油。


    解决方案:

    我会做如下的事情:

    # 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"
    

    我为什么推荐上述解决方案:

    首先,(希望有明显的原因)我无法测试和确认上述解决方案在所有方面都能成功运行。 *尼克斯风味 . 第二,如果我不这么说,那就太天真了,因为(我相信你知道),那里是一个古老的大景观,也就是说,那里有很多版本、味道和变体。

    基于以下发现/研究,我得出了上述解决方案的结论。的味道 *尼克斯 下面的支持/兼容性表中包含的内容还远远不够详尽。我从列出的口味中选了它们 here .

    大多数被选中者 香料 是由志愿者小组开发的,他们可以免费使用(开放式BSD、免费BSD等)。幸运的是,文档、手册页等 *NIX香料 在网上发布,它们一直是我决策的主要影响因素。IBM AIX和Sun的Solaris是例外,因为它们是专有的,但是这两个系统中有一些文档、手册页等可用。


    支持/兼容性表

    • 这个 tar --delete 选项

      首先,我们来看一下 tar 命令 --delete 选择权。正如您在下表中看到的,它远没有得到广泛的支持 :( 因此,为什么有必要采用更详细的解决方案——不幸的是,当跨平台是一项需求时,我们不能使用一行程序。

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

      上述解决方案利用了 焦油 期权,即: -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  │  √   │  ?   │  √  │      √       │   √   │    √    │
      └─────────────┴─────┴──────┴──────┴─────┴──────────────┴───────┴─────────┘
      

      如你所见,我们很好地利用 射频-射频 因为它得到了很好的支持。

      谨小慎微 mktemp

      建立临时文件 而且它的 -t -d 这种选择似乎得到的支持不那么广泛。(注:我不确定是否支持免费的BSD,因此 ? 指示器)。

      所以,虽然我建议的解决方案确实利用了 建立临时文件 ,您可能想使用 mkdir -p 相反,由于下表所示得到了广泛支持:

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

    工具书类

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

    1. 焦油

    2. mktemp -d -t

    3. 射频-射频

    4. MKDIR

    5. 其他