Here is another solution. It won't let you extract individual files from an archive and reduce its size, but it does let you extract all files reducing the size of the archive as you go:
#!/bin/sh
# $1, the first paramter, is the .tar.gz file to unarchive
(
size=$(wc -c $1)
offset=0
bs=4096
while [[ $size > $offset ]]; do
dd if=$1 bs=$bs count=1 skip=$offset status=none
fallocate -p -o $offset -l $bs $1
offset=$(( $offset + $bs ))
done
) | tar xz
Save this into a file like e.g. untar_and_destroy.sh
and execute as:
untar_and_destroy.sh whatever.tar.gz
What this does is give part of the .tar.gz
file to tar, asks Linux to deallocate that part of the file, and then repeats for the next part. When you are done, ls -l
will say the .tar.gz
files has the same size as before, but du
will report its size as 0. This is because the .tar.gz
has been made into a sparse file, with the same length as before but as all 0s that don't need to be stored onto disk.
Don't use this in production, or anywhere where having that archive deleted would be bad. This makes the archive unreadable as soon as it starts, so if anything goes wrong, e.g. you run out of hard disk space while extracting, you won't get a second chance to run this.