开发者

Extract a .tgz into specific subfolder only if there are files in the tar that would extract to my CWD

开发者 https://www.devze.com 2023-04-10 02:14 出处:网络
Most tar files extract into their own subfolder (because the people that write open source utilities are amazing people).

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


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号