bash - 如何就地从 tarball 中删除空目录
问题描述
我从一个 docker 镜像中提取了一个层,该镜像归档在一个名为 layer.tar 的文件中。我想从中删除空目录。
我不想解压缩然后重新打包该存档中的文件,我想保留原始信息,所以我想就地进行。
我知道如何从 tar 中删除文件,但我不知道任何简单的方法来就地删除空目录。
解决方案
让我们创建一个包含空目录a/b/c/
的存档 t.tar :a/b/c/d/
mkdir -p dir
cd dir
mkdir -p a/b/c/d
mkdir -p 1/2/3/4
touch a/fil_ea a/b/file_ab # directory a/b/c and a/b/c/d are empty
touch 1/2/3/file_123 1/2/3/4/file_1234 # directories 1/2/3/4 not empty
tar cf ../t.tar a 1
cd ..
使用tar tf
和一些过滤,我们可以提取 tar 存档中的目录和文件。然后对于其中的每个目录,tmpdirs
我们可以使用简单的 grep 检查它是否有任何文件tmpfiles
,然后使用--delete
tar 选项删除这些目录:
tar tf t.tar | tee >(grep '/$' > tmpdirs) | grep -v '/$' > tmpfiles
cat tmpdirs | xargs -n1 -- sh -c 'grep -q "$1" tmpfiles || echo "$1"' -- \
| tac \
| xargs -- tar --delete -f t.tar
并不是说 tac 有点不需要,而是文件在 tar 中按字母顺序排序,因此当 tara/b/c/
首先删除包含所有子目录的目录然后尝试删除a/b/c/d/
目录时,它会失败并出现Not found in archive
错误。tac
是一种廉价的解决方法,因此 tar 首先删除a/b/c/d/
然后a/b/c/
.
推荐阅读
- javascript - 错误:由于 MIME 类型(“text/html”)不匹配而被阻止(X-Content-Type-Options: nosniff)
- javascript - 通过 JS 访问单个 SQLAlchemy 对象
- android - 如何更改edittext放大镜的字体颜色
- php - WordPress 定制器选项无法正常工作
- sorbet - 如何正确运行“srb tc --lsp”?
- python - POST 请求给出错误但我给出所有标题和表单数据
- c# - Autofac 的 `reloadOnChange` 不会重新加载配置?
- javascript - 是否有可能仅使用 JavaScript 来保护数据?
- javascript - 即使窗口/外部 div 发生变化,div 也总是相互匹配
- c# - 仅当滚动条位于底部时才添加文本时自动滚动 - c# winforms