In place untar and delete tar (or tar.gz) - shell

I have this tiny code here
for i in *.tar.gz;
do tar xzvf $i;
done && find . -name "*.tar.gz" -exec rm {} \;
Now, when I have multiple tars, it will first untar all of them and then delete the tar files.
How can I change the code to untar a file, to delete it and then move to the next tar file?
Thanks in advance

for file in *.tar.gz; do tar xzvf "${file}" && rm "${file}"; done
Don't forget to quote your variables to account for funky filenames with whitespace.

Simply change the order of actions:
for i in *.tar.gz; do
tar xzvf "$i" && rm -r "$i"
done

Related

How do I set case for tar, gz and tar.gz files?

I have few files in a directory like this:
xxx.tar.gz
xxx.tar
yyy.tar.gz
yyy.tar
zzz.txt.gz
...
...
I have list.txt for files like this:
list.txt:
/home/phe/xxx.tar.gz
/home/phe/xxx.tar
/home/phe/yyy.tar.gz
/home/phe/yyy.tar
/home/phe/zzz.txt.gz
...
...
I need to extract these files like this:
for file in (cat list.txt); do
tar zxvf $file
done
How can I open tar.gz, txt.gz and tar files in same command?
You could do something like that:
while IFS= read -r file; do
file="${file##*/}" # remove the directory
case $file in
*.tar.gz)
tar xzvf "$file"
;;
*.txt.gz)
gzip -d "$file"
;;
esac
done < list.txt
Note that for the tar command I suspect you would need to specify some output directory with -C because otherwise everything will be extracted in the current directory.
If I'm reading your question right and the .txt.gz files are just gzipped, the .tar.gz files are tarballs, and the .tar files are simply tar archives, without compression, then you could do something like the following:
while read -r file; do
tmp = "${file##*/}"
[ "${tmp:3:3}" = "txt" ] && gzip -dk "$file" ## remove k to delete original
[ "${tmp##.}" = "tar" ] && tar -xvf "$file"
[ "${tmp##.}" = "gz" ] && tar -xvzf "$file"
done <list.txt
If the files are no longer in their original directories (as shown in the list.txt file), change tmp to file above.

How to untar all tar files in current directory using Putty

How can I untar all tar files in one command using Putty.
I Tried the following but its not un-tarring (all files start with alcatelS*)
tar -xfv alcatelS*.tar
It is not working i don't get no errors and it is not un-tarring.
Thank you,
-xfv is wrong since v is being referred as the file instead. Also, tar can't accept multiple files to extract at once. Perhaps -M can be used but it's a little stubborn when I tried it. Also, it would be difficult to pass multiple arguments that were extracted from pathname expansion i.e. you have to do tar -xvM -f file1.tar -f file2.tar.
Do this instead:
for F in alcatelS*.tar; do
tar -xvf "$F"
done
Or one-line: (EDIT: Sorry that -is- a "one"-liner but I find that not technically a real one-liner, just a condensed one so I should haven't referred to that as a one-liner. Avoid the wrong convention.)
for F in alcatelS*.tar; do tar -xvf "$F"; done
You can use following command for extract all tar.gz files in directory in unix
find . -name 'alcatelS*.tar.gz' -exec tar -xvf {} \;
Following is my favorite way to untar multiple tar files:
ls *tar.gz | xargs -n1 tar xvf
Can be done in one line:
cat *.tar | tar -xvf - -i

Loop with variable in bash script

I deploy my website using a post-receive git hook. Within that hook I use the YUI compressor to minify js and css files:
export TEMP=/var/www/example.com
GIT_WORK_TREE=/var/www/example.com git checkout master -f
#Minify mit YUI
(cd $TEMP/css && min style.css && rm style.css && mv style.min.css style.css)
(cd $TEMP/addons/css && min bootstrap.css && rm bootstrap.css && mv bootstrap.min.css
(cd $TEMP/js && min script.js && rm script.js && mv script.min.js script.js)
(cd $TEMP/addons/js && min startup.js && rm startup.js && mv startup.min.js startup.js)
Now I would like to not specify the exact files, but to search for all js and css files through all folders in $TEMP and repeat the minify procedure each time.
Could any one help me with the right loop and search-syntax for this case?
Thanks!
Just a guess here, but what about constructs like this?
find $TEMP -name \*.css -exec sh -c 'f="{}"; min "$f" && mv "${f%.css}.min.css" "$f"' \;
The idea is that the find command finds all your CSS files, then executes the min and mv commands. No need to rm, as the mv will overwrite.
You can probably figure out the equivalent line for your JavaScript files. :-)
Note that I haven't tested this, as I don't use min, but this isn't a question about minifying or YUI, it's a question about how to execute a command on multiple files in a directory tree.
UPDATE:
You can skip some files by putting extra logic into the find conditions:
find $TEMP -name \*.js -and -not -name \*.min.js -exec ...
In a single command line using bash terminal:
TEMP="/var/www/example.com"; pwd="$PWD"; IFS=$'\n'; for f in `find $TEMP -name "*.js" -or -name "*.css"`; do dir=`dirname $f`; cd "$dir"; min "$f"; ext="${f##*.}"; f2=`echo $f | sed "s/$ext$/min\.$ext/g"`; rm -f "$f"; mv "$f2" "$f"; done; cd "$pwd"
or if you place it in a sh file, then:
#!/bin/bash
TEMP="$1";
IFS=$'\n';
for f in `find $TEMP -name "*.js" -or -name "*.css"`; do
dir=`dirname $f`
cd "$dir"
min "$f"
ext="${f##*.}"
f2=`echo $f | sed "s/$ext$/min\.$ext/g"`
rm -f "$f"
mv "$f2" "$f"
done
and call the script with the path as an argument or hardcode it directly into the file.
The above algorithm takes care of both js and css files. It moves into the directory where the file is located and create the temporary file in that very same directory, as your original command does. It also should work even if you have spaces in file or directory names or if files contain the substring .js or .css within their names and not only in the extension.

How to untar specific files from a number of tar files and zip them?

The requirement is to extract all the *.properties files from multiple tars and put them into a zip.
I tried this:
find . -iwholename "*/ext*/*.tar.gz"|xargs -n 1 tar --wildcards '*.properties' -xvzf | zip -# tar-properties.zip
This is creating a zip with the .properties files in all the tars.
But the issue is the tars are structured as in each tar contains a properties folder which contains the files. The above command is creating a zip with a single properties folder which contains all the files .
Is there a way to put these in the zip with a folder structure like {name of the tar}/properties/*.properties ?
You could use this script. My solution uses --transform as well. Please check first if your tar command supports it with tar --help 2>&1 | grep -Fe --transform.
#!/bin/bash
[ -n "$BASH_VERSION" ] || {
echo "You need bash to run this script." >&2
exit 1
}
TEMPDIR=/tmp/properties-files
OUTPUTFILE=$PWD/tar-properties.zip ## Must be an absolute path.
IFS=
if [[ ! -d $TEMPDIR ]]; then
mkdir -p "$TEMPDIR" || {
echo "Unable to create temporary directory $TEMPDIR." >&2
exit 1
}
fi
NAMES=()
while read -r FILE; do
NAMEOFTAR=${FILE##*/} ## Remove dir part.
NAMEOFTAR=${NAMEOFTAR%.tar.gz} to remove extension ## Remove .tar.gz.
echo "Extracting $FILE."
tar --wildcards '*.properties' -xvzf "$FILE" -C "$TEMPDIR" --transform "s#.*/#${NAMEOFTAR//#/\\#}/properties/#" || {
echo "An error occurred extracting to $TEMPDIR." >&2
exit 1
}
NAMES+=("$NAMEOFTAR")
done < <(exec find . -type f -iwholename '*/ext*/*.tar.gz')
(
cd "$TEMPDIR" >/dev/null || {
echo "Unable to change directory to $TEMPDIR."
exit 1
}
zip -a "$OUTPUTFILE" "${NAMES[#]}"
)
Save it to a script then run it on the directory where those files are to be searched with
bash /path/to/script.sh`
You can probably do the trick with tar option --transform, --xform. This option permits to manipulate path thanks to a sed expression.
find . -iwholename "*/ext*/*.tar.gz"|xargs -n 1 tar --wildcards '*.properties' -xvzf --xform 's#.*/#name_of_the_tar/properties/#' | zip -# tar-properties.zip

untar filename.tr.gz to directory "filename"

I would like to untar an archive e.g. "tar123.tar.gz" to directory /myunzip/tar123/" using a shell command.
tar -xf tar123.tar.gz will decompress the files but in the same directory as where I'm working in.
If the filename would be "tar233.tar.gz" I want it to be decompressed to /myunzip/tar233.tar.gz" so destination directory would be based on the filename.
Does anyone know if the tar command can do this?
tar -xzvf filename.tar.gz -C destination_directory
With Bash and GNU tar:
file=tar123.tar.gz
dir=/myunzip/${file%.tar.gz}
mkdir -p $dir
tar -C $dir -xzf $file
You can change directory before extracting with the -C flag, but the directory has to exist already. (If you create file-specific directories, I strongly recommend against calling them foo.tar.gz - the extension implies that it's an archive file but it's actually a directory. That will lead to confusion.)
Try
file=tar123.tar.gz
dir=/myunzip/$(basename $file .tar.gz) # matter of taste and custom here
[ -d "$dir" ] && { echo "$dir already exists" >&2; exit 1; }
mkdir "$dir" && ( gzip -d "$file | ( cd "$dir" && tar xf - ) )
If you're using GNU tar you can also give it an option -C "$dir" which will cause it to change to the directory before extracting. But the code above should work even with a Bronze Age tar.
Disclaimer: none of the code above has been tested.

Resources