Extract a .tgz into specific subfolder only if there are files in the tar that would extract to my CWD
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!
精彩评论