从 tar 文件中查找提取的目录名称

从 tar 文件中查找提取的目录名称

我有一个项目,我正在下载并编译一堆文件。我可以对此文件做出的假设是:

  • 只会有一个顶级目录
  • 文件夹名称不一定与 tar.xz/gz 文件名匹配(换句话说,something-1.3.5a.tar.gz 可能会提取到名为 Something-1.3.5 的文件夹中)

为了减少打字量,我写了一个小脚本,其中包括执行以下操作:

  • 提取 tar.xz/gz 文件
  • cd 进入目录

我目前的黑客是做这样的事情:

test1=$(tar -axvf something-1.3.5a.tar.gz)

cd $(echo $test1 | cut -f1 -d" ")

基本上,它的作用是捕获提取的输出,并获取第一行(这是顶级目录),然后 cd 进入其中。

所以,我的问题是,有没有更干净/更好的方法来做到这一点?

答案1

#!/bin/sh
Dir_name=`tar -tzf something-1.3.5a.tar.gz | head -1 | cut -f1 -d"/"`
echo $Dir_name

tar options details,
-t, --list 
-z, --gzip, --ungzip               filter the archive through gzip
-f, --force-local              archive file is local even if has a colon

在这里,我们获取 tar 中的文件列表,并使用head -1cmd 获取第一行,使用 cut cmd 提取第一个字段。

答案2

如果您只有一个顶级目录,但什么也没有,您可以在运行 tar 之前记住有哪些目录,并在运行 tar 后查看您拥有的内容(假设没有其他人更改过该目录)。

 # ksh terminology: set -A BEFORE .*/ */
 BEFORE=(.*/ */)
 tar -xf blah blah blah
 AFTER=(.*/ */)
 # We can make it O(n), since glob outputs can be assumed to be sorted.
 # Do it.
 for (( i = 0; i < "${#BEFORE[@]}"; i++ )); do
    [ "${BEFORE[i]}" == "${AFTER[i]}" ] || break
 done
 cd "${AFTER[i]}"

这应该适用于所有具有算术for、从零索引开始的数组以及用于${#arr[@]}访问数组成员计数的 shell。

实际上存在一个问题,因为*/可能会扩展到字面上*/没有匹配的地方。在bash(假设您因为标记而使用 bash)中,您可以进行设置shopt -s nullglob

使用*/将通配项限制为目录,因此您不必担心文件 - 额外的文件仍然使其只有一个目录:)

答案3

使用 tar.bz2 文件,不要得到如下内容:

0               0 2019-04-02 17:20 folder name

我正在使用 -tf 选项:

tar -tf file_name.tar.bz2 | head -1 | cut -f1 -d"/"

相关内容