Não é possível fazer isso exatamente no lugar.
Talvez algo que você possa usar seja a solução sugerida nesta resposta: No local, extraia o arquivo tar
archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
currentchunk=$((currentchunk-1))
done
O que ele faz é copiar uma parte do arquivo em outro arquivo e excluí-lo imediatamente do original.
Desta forma, você só precisa de 1MB de espaço livre em disco (supondo que você tenha dividido em 1MB).
EDITAR: Se você tiver zero de espaço livre em disco, mas tiver memória suficiente, poderá criar um disco virtual e armazenar cada parte enquanto exclui o bloco original. Ainda não testou:
ramsize=4096
rammount=/ramdisk
archive="archive.tar"
chunkprefix="$rammount/chunk_"
# 1-Mb chunks :
chunksize=1048576
mkdir $rammount
mkfs -q /dev/ram1 $ramsize
mount /dev/ram1 $rammount
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
# copy the chunk on disk
cp "$chunkprefix$currentchunk" .
currentchunk=$((currentchunk-1))
done
É exatamente o mesmo script, exceto que ele começa criando e montando um disco RAM de 4 MB e armazena temporariamente cada fragmento até que libere espaço truncando o arquivo original.