Вам придется распаковать, изменить, а затем повторно сжать файлы. Обойти это невозможно.
Однако это не обязательно включает запись файла в хранилище. Возможно, вы сможете вносить изменения, которые вам нравятся, в режиме streaming , то есть, что все выполняется только в памяти без полного распакованного файла. Unix использует каналы для таких задач.
Вот пример того, как это сделать:
- Создать два случайных файла:
echo "hello world" > a
echo "hello world" > b
Создать сжатый архив, содержащий оба:
tar -c -z -f x.tgz a b
Передача содержимого несжатого архива через чейнджер. К сожалению, я не нашел никакого способа сделать это на основе оболочки, но вы также указали Python в тегах, и с помощью модуля
tarfile
вы можете добиться этого:
Вот файл tar.py
:
#!/usr/bin/env python3
import sys
import tarfile
tar_in = tarfile.open(fileobj=sys.stdin.buffer, mode='r:gz')
tar_out = tarfile.open(fileobj=sys.stdout.buffer, mode='w:gz')
for tar_info in tar_in:
reader = tar_in.extractfile(tar_info)
if tar_info.path == 'a': # my example file names are "a" and "b"
# now comes the code which makes our change:
# we just skip the first two bytes in each file:
reader.read(2) # skip two bytes
tar_info.size -= 2 # reduce size in info object as well
# add the (maybe changed) file to the output:
tar_out.addfile(tar_info, reader)
tar_out.close()
tar_in.close()
Это можно назвать так:
./tar.py < x.tgz > y.tgz
y.tgz
снова будет содержать оба файла, но в a
первые два байта будут пропущены (поэтому его содержимое будет llo world
).
Вы заметите, что вам нужно заранее знать размер изменения. tar
предназначен для обработки файлов , и поэтому ему необходимо записать размер входных файлов в дейтаграмму tar info, которая предшествует каждому входному файлу в результирующем файле, поэтому я не вижу никакого способа обойти это. С сжатым выводом также невозможно пропустить назад после записи всего вывода и отрегулировать размер файла.
Но, как вы сформулировали свой вопрос, это может быть возможно в вашем случае.
Все, что вам нужно сделать, это предоставить файлоподобный объект (может быть Popen
выходной поток объекта), такой как reader
в моем простом примере.