仅当 tar 中存在可提取到我的 CWD 的文件时,才将 .tgz 提取到特定子文件夹中

发布于 2024-12-07 15:53:29 字数 938 浏览 3 评论 0原文

大多数 tar 文件都会解压到自己的子文件夹中(因为编写开源实用程序的人都是了不起的人)。

有些提取到我的 cwd 中,这使所有内容变得混乱。我知道有一种方法可以查看 tar 中的内容,但我想编写一个 bash 脚本,从本质上保证我最终不会将 15 个文件提取到我的主文件夹中。

有什么指点吗?

伪代码:

if [listing of tar files] has any file that doesn't have a '/' in it:
    mkdir [tar filename without extension]
    tar xzvf [tar filename] into [the new folder]
else:
    tar xzvf [tar filename] into cwd

编辑:

两种解决方案都很棒,我选择以下解决方案是因为我要求 bash 脚本,并且它不依赖额外的软件。

然而,在我自己的机器上,我使用 aunpack 因为它可以处理很多很多格式。

我将它与 shell 脚本一起使用,该脚本可以一次下载并解压所有内容。这是我正在使用的:

#!/bin/bash
wget -o temp.log --content-disposition $1
old=IFS
IFS='
'
r=`cat temp.log`
rm temp.log
for line in $r; do
    substring=$(expr "$line" : 'Saving to: `\(.*\)'\')
    if [ "$substring" != "" ]
    then
        aunpack $substring
        rm $substring
        IFS=$old
        exit
    fi
done
IFS=$old

Most tar files extract into their own subfolder (because the people that write open source utilities are amazing people).

Some extract into my cwd, which clutters everything up. I know there's a way to see what's in the tar, but I want to write a bash script that essentially guarantees I won't end up with 15 files extracted into my home folder.

Any pointers?

pseudo code:

if [listing of tar files] has any file that doesn't have a '/' in it:
    mkdir [tar filename without extension]
    tar xzvf [tar filename] into [the new folder]
else:
    tar xzvf [tar filename] into cwd

EDIT:

Both solutions are great, I chose the below solution because I was asking for a bash script, and it doesn't rely on extra software.

However, on my own machine, I am using aunpack because it can handle many, many more formats.

I am using it with a shell script that downloads and unpacks all at once. Here is what I am using:

#!/bin/bash
wget -o temp.log --content-disposition $1
old=IFS
IFS='
'
r=`cat temp.log`
rm temp.log
for line in $r; do
    substring=$(expr "$line" : 'Saving to: `\(.*\)'\')
    if [ "$substring" != "" ]
    then
        aunpack $substring
        rm $substring
        IFS=$old
        exit
    fi
done
IFS=$old

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风情万种。 2024-12-14 15:53:29

atool 包中的 aunpack 命令执行以下操作:

aunpack 从存档中提取文件。通常人们想要提取所有
将存档中的文件复制到单个子目录中。
但是,某些存档的根目录中包含多个文件
目录。 aunpack 程序克服了这个问题
首先将文件提取到一个唯一的(临时的)
目录,然后如果可能的话将其内容移回原处。这
还可以防止本地文件被错误覆盖。

The aunpack command from the atool package does that:

aunpack extracts files from an archive. Often one wants to extract all
files in an archive to a single subdirectory.
However, some archives contain multiple files in their root
directories. The aunpack program overcomes this problem
by first extracting files to a unique (temporary)
directory, and then moving its contents back if possible. This
also prevents local files from being overwritten by mistake.

清风夜微凉 2024-12-14 15:53:29

您可以使用 tar 选项的组合来实现此目的:
用于列出的 tar 选项是:

   -t, --list
          list the contents of an archive

tar 提取到不同目录的选项是:

   -C, --directory DIR
          change to directory DIR

因此,在您的脚本中,您可以列出文件和文件。检查列表中是否有任何文件没有“/”,并根据该输出,您可以使用适当的选项调用 tar
供您参考的示例如下:

TAR_FILE=<some_tar_file_to_be_extracted>
# List the files in the .tgz file using tar -tf
# Look for all the entries w/o "/" in their names using grep -v 
# Count the number of such entries using wc -l, if the count is > 0, create directory
if [ `tar -tf ${TAR_FILE} |grep -v "/"|wc -l` -gt 0 ];then
   echo "Found file(s) which is(are) not in any directory"
   # Directory name will be the tar file name excluding everything after last "."
   # Thus "test.a.sh.tgz" will give a directory name "test.a.sh"
   DIR_NAME=${TAR_FILE%.*}
   echo "Extracting in ${DIR_NAME}"
   # Test if the directory exists, if not then create it
   [ -d ${DIR_NAME} ] || mkdir ${DIR_NAME}
   # Extract to the directory instead of cwd
   tar xzvf ${TAR_FILE} -C ${DIR_NAME}
else
   # Extract to cwd
   tar xzvf ${TAR_FILE}
fi

在某些情况下,tar 文件可能包含不同的目录。如果您发现查找由同一 tar 文件提取的不同目录有点烦人,那么可以修改脚本来创建新目录,即使列表包含不同的目录。稍微高级的示例如下:

TAR_FILE=<some_tar_file_to_be_extracted>
# List the files in the .tgz file using tar -tf
# Look for only directory names using cut, 
# Current cut option used lists each files as different entry 
# Count the number unique directories, if the count is > 1, create directory
if [ `tar -tf ${TAR_FILE} |cut -d '/' -f 1|uniq|wc -l` -gt 1 ];then
   echo "Found file(s) which is(are) not in same directory"
   # Directory name will be the tar file name excluding everything after last "."
   # Thus "test.a.sh.tgz" will give a directory name "test.a.sh"
   DIR_NAME=${TAR_FILE%.*}
   echo "Extracting in ${DIR_NAME}"
   # Test if the directory exists, if not then create it
   # If directory exists prompt user to enter directory to extract to
   # It can be a new or existing directory
   if [ -d ${DIR_NAME} ];then
     echo "${DIR_NAME} exists. Enter (new/existing) directory to extract to"
     read NEW_DIR_NAME
     # Test if the user entered directory exists, if not then create it
     [ -d ${NEW_DIR_NAME} ] || mkdir ${NEW_DIR_NAME}
   else
     mkdir ${DIR_NAME}
   fi
   # Extract to the directory instead of cwd
   tar xzvf ${TAR_FILE} -C ${DIR_NAME}
else
   # Extract to cwd
   tar xzvf ${TAR_FILE}
fi

希望这会有所帮助!

You can use combination of tar options to achieve this:
tar option for listing is:

   -t, --list
          list the contents of an archive

tar option to extract into different directory is:

   -C, --directory DIR
          change to directory DIR

So in your script you can list the files & check if there are any files in the listing which do not have "/" and based on that output you can call tar with appropriate options.
Sample for your reference is as follows:

TAR_FILE=<some_tar_file_to_be_extracted>
# List the files in the .tgz file using tar -tf
# Look for all the entries w/o "/" in their names using grep -v 
# Count the number of such entries using wc -l, if the count is > 0, create directory
if [ `tar -tf ${TAR_FILE} |grep -v "/"|wc -l` -gt 0 ];then
   echo "Found file(s) which is(are) not in any directory"
   # Directory name will be the tar file name excluding everything after last "."
   # Thus "test.a.sh.tgz" will give a directory name "test.a.sh"
   DIR_NAME=${TAR_FILE%.*}
   echo "Extracting in ${DIR_NAME}"
   # Test if the directory exists, if not then create it
   [ -d ${DIR_NAME} ] || mkdir ${DIR_NAME}
   # Extract to the directory instead of cwd
   tar xzvf ${TAR_FILE} -C ${DIR_NAME}
else
   # Extract to cwd
   tar xzvf ${TAR_FILE}
fi

In some cases the tar file may contain different directories. If you find it a little annoying to look for different directories which are extracted by the same tar file then the script can be modified to create a new directory even if the listing contains different directories. The slightly advanced sample is as follows:

TAR_FILE=<some_tar_file_to_be_extracted>
# List the files in the .tgz file using tar -tf
# Look for only directory names using cut, 
# Current cut option used lists each files as different entry 
# Count the number unique directories, if the count is > 1, create directory
if [ `tar -tf ${TAR_FILE} |cut -d '/' -f 1|uniq|wc -l` -gt 1 ];then
   echo "Found file(s) which is(are) not in same directory"
   # Directory name will be the tar file name excluding everything after last "."
   # Thus "test.a.sh.tgz" will give a directory name "test.a.sh"
   DIR_NAME=${TAR_FILE%.*}
   echo "Extracting in ${DIR_NAME}"
   # Test if the directory exists, if not then create it
   # If directory exists prompt user to enter directory to extract to
   # It can be a new or existing directory
   if [ -d ${DIR_NAME} ];then
     echo "${DIR_NAME} exists. Enter (new/existing) directory to extract to"
     read NEW_DIR_NAME
     # Test if the user entered directory exists, if not then create it
     [ -d ${NEW_DIR_NAME} ] || mkdir ${NEW_DIR_NAME}
   else
     mkdir ${DIR_NAME}
   fi
   # Extract to the directory instead of cwd
   tar xzvf ${TAR_FILE} -C ${DIR_NAME}
else
   # Extract to cwd
   tar xzvf ${TAR_FILE}
fi

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文