в принципе, то, что вам нужно, это возможность трубы файл в смолу, и" лопнуть " фронт, как вы идете.
на StackOverflow, кто-то спросил как обрезать файл спереди, но, кажется, это невозможно. Вы все еще можете заполнить начало файла нулями особым образом, чтобы файл стал разреженным файлом, но я не знаю как это сделать. Хотя мы можем обрезать конец файла. Но tar должен прочитать архив вперед, не назад.
Решение 1
уровень косвенности решает все проблемы. Сначала переверните файл на месте, затем прочитайте его назад (что приведет к чтению исходного файла вперед) и усеките конец перевернутого файла, когда вы идете.
вам нужно написать программу (c, python, что угодно), чтобы обменять начало и конец файла, кусок за куском, а затем передать эти куски в tar при усечении файла кусок в время. Это основа для решения 2, которое, возможно, проще реализовать.
решение 2
другой способ-это разбить файл на небольшие блоки на месте, удалите эти куски, как мы извлекаем их. Код ниже имеет размер одного мегабайта, настраивается в зависимости от ваших потребностей. Большой быстре но примет больше промежуточного космоса разделяя и во время извлечения.
разделить файловый архив.смола :
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
передать эти файлы в tar (обратите внимание, что нам нужна переменная chunkprefix во втором терминале):
mkfifo fifo
# In one terminal :
(while true; do cat fifo; done) | tar -xf -
# In another terminal :
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done > fifo
# When second terminal has finished :
# flush caches to disk :
sync
# wait 5 minutes so we're sure tar has consumed everything from the fifo.
sleep 300
rm fifo
# And kill (ctrl-C) the tar command in the other terminal.
так как мы используем именованный канал (mkfifo fifo
), вам не нужно трубить все куски сразу. Это может быть полезно, если вы действительно ограничены в пространстве. Вы можете выполнить следующие действия :
- переместить, скажем, последние 10 Гб куски на другой диск,
- начать извлечение с кусками вы все еще есть,
- когда
while [ -e … ]; do cat "$chunk…; done
цикл завершен (второй терминал):
- не останавливайте
tar
команда, не удаляйте fifo (первый терминал), но вы можете запустить sync
на всякий случай
- переместите некоторые извлеченные файлы, которые, как вы знаете, завершены (tar не останавливается в ожидании завершения извлечения этих файлов), на другой диск,
- переместите оставшиеся куски назад,
- возобновить извлечение, запустив
while [ -e … ]; do cat "$chunk…; done
строки снова.
конечно, это все от Haute voltige, вы хотите, чтобы проверить все в порядке на фиктивный архив сначала, потому что если вы допустили ошибку, то до свидания данных.
вы никогда не будете знать, если первый терминал (tar
) фактически закончил обработку содержимого fifo, поэтому, если вы предпочитаете, вы можете запустить это вместо этого, но у вас не будет возможности легко обмениваться кусками с другим диск:
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done | tar -xf -
отказ от ответственности
обратите внимание, что для того, чтобы все это работало, ваша оболочка, tail и truncate должны корректно обрабатывать 64-битные целые числа (для этого вам не нужен 64-битный компьютер или операционная система). Мой делает, но если вы запустите приведенный выше сценарий в системе без этих требований,вы потеряете все данные в архиве.tar.
и в любом случае что-то кроме этого пойдет не так, вы потеряете все данные в архиве.ТАР в любом случае, поэтому убедитесь, что у вас есть резервная копия ваших данных.