Я хочу просмотреть содержимое файла tarred, не распаковывая его, Сценарий: у меня есть .tar, а внутри есть файл с именем ./x/y.txt. Я хочу, чтобы просмотреть содержание y.txtбез фактического извлечения a.tar.
Я хочу просмотреть содержимое файла tarred, не распаковывая его, Сценарий: у меня есть .tar, а внутри есть файл с именем ./x/y.txt. Я хочу, чтобы просмотреть содержание y.txtбез фактического извлечения a.tar.
Ответы:
Вероятно, это специфическая опция GNU, но вы можете использовать -Oили --to-stdoutдля извлечения файлов в стандартный вывод
$ tar -axf file.tgz foo/bar -O
tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Oнапример, когда совпадают многие файлы *read_this_file*. Все печатается на одной строке. Из того man, что я нашел --to-command. так что прохождение --to-command="echo '' && cat"- это немного чёрной магии, но это работает: D
$ tar -axf file.tgz foo/bar -O
Это печатает содержимое ./x/y.txt из a.tar в STDOUT.
tar xfO a.tar ./x/y.txt
Это просто как
less a.tar:./x/y.txt
Этот магический трюк работает, если вы lesspipeустановили и если переменная env LESSOPENопределена как | /usr/bin/lesspipe.sh %sожидаемая, если вы правильно установили lesspipe .
lesspipe.sh должно быть предпочтительнее.
Да, но это вопрос о содержании файла в tarфайле. И на самом деле, в некоторых случаях это не так сложно. Дело в том, что tarфайл - это просто заблокированный файл потока - каждый файл в архиве находится после предыдущего, и каждый файл получает заголовок метаданных на основе указанного формата .
Основываясь на этом формате, я однажды написал shitar- это было несколько строк ddи сценариев оболочки, которые могли tarна лету создавать поток блочных устройств. Основываясь на том же, совсем недавно я написал эти несколько строк кода :
tar --no-recursion -c ./ |
{ printf \\0; tr -s \\0; } |
cut -d '' -f-2,13 |
tr '\0\n' '\n\t'
... для выделения tarфайла на лету и выполнения встроенных преобразований в его компонентных текстовых файлах. Там cutполя указывают на поля 1,2,13 строки ввода, разделенной NUL . Подобные вещи просты, когда tarфайл содержит только текстовые файлы, потому что tarразделители записей (которые могут появляться один раз каждые 512 байт) могут быть просто сжаты до одного NUL за каждый и удалены - без необходимости подсчитывать вхождения, как вы это делаете.
tarФормат заголовка выглядит так:
field offset len
name 0 100
mode 100 8
uid 108 8
gid 116 8
size 124 12
mtime 136 12
chksum 148 8
typeflag 156 1
linkname 157 100
magic 257 6
version 263 2
uname 265 32
gname 297 32
devmajor 329 8
devminor 337 8
prefix 345 155
Поймите, что между относительной простотой обработки простых tarопераций и значительно более сложными аспектами формата архива существует крутой наклон . В то время как простые вещи - например, объединение небольшой группы однородно типизированных файлов или даже разделение архива, содержащего только элементы, типы которых вы можете предсказать, - можно легко выполнить с помощью нескольких оболочек, надежная обработка произвольных элементов архива - не пустяк.
Это особенно трудно, когда эти члены могут содержать произвольные двоичные данные - что, безусловно, исключает какое-либо надежное применение tr -s- и эта сложность возникает только тогда, когда используются файлы различных типов, отличные от обычных и / или кодировки, отличные от вашего собственного, и / или Исходный архив был создан реализацией с особенностями приложения формата, с которыми вы не готовы работать. И это касается только основных стандартизированных аспектов типа tarархива - добавьте расширенные заголовки, расширения форматов, разреженные файлы и сжатие и ... что ж, удачи в этом.
Возвращаясь к основам, однако, стандартный размер записи для tarархива составляет 20 блоков - или 10240 байт. Однако, учитывая, что архив заблокирован по стандартному размеру записи и содержит только стандартные типы файлов и стандартные ustarзаголовки, следует переходить от заголовка члена к заголовку члена, выполняя операции чтения в соответствии с sizeполем заголовка, пока не будет найден элемент, соответствующий элементу для который ты ищешь. Оказавшись там, прочитайте sizeбайты от смещения, начинающегося в хвосте заголовка члена вашей цели. И это ваш файл.
Пропускать заголовки не так уж и легко. К разным типам будут добавлены или не будут добавлены фактические блоки данных, соответствующие size. Например, каталоги и ссылки не будут содержать такого блока данных, только описание заголовка, и поэтому вы должны быть готовы проверить тип файла текущего заголовка, прежде чем точно определить, следует ли применять его sizeполе к формуле пропуска или нет.
Кроме того, факторы размера записи - в зависимости от того, хорошо ли синхронизируются размеры элементов архива со стандартным размером записи 10240 - может ли или не быть дополнительный 0-блок добавлен к каждому. И размер записи может быть объявлен во время создания архива - и поэтому он может даже не составлять 20 блоков, хотя, по спецификации, он всегда должен быть заблокирован на 512-байтовых блоках:
tarобмена; смотрите раздел РАСШИРЕННОЕ ОПИСАНИЕ . Размер блока по умолчанию для этого формата для символьных специальных архивных файлов должен быть 10240 . Реализации должны поддерживать все значения размера блока, меньшие или равные 32256 , кратные 512 .Поэтому, если вы работаете с tarфайлом, который может содержать файлы, которые могут содержать произвольные двоичные данные, вам придется пропустить файл алгоритмически и в соответствии с типом файла. В спецификации сказано:
sizeПоле размер файла в октетах.
typeflagполе указано, что файл должен иметь тип 1 ( ссылка ) или 2 ( символьная ссылка ) , sizeполе должно быть указано как ноль.typeflagполе задано указание файла типа 5 ( каталог ) , это sizeполе следует интерпретировать, как описано в определении этого типа записи.typeflagполя установлено значение 3 ( специальный символьный файл) , 4 ( специальный блочный файл) или 6 ( FIFO ) , значение sizeполя не определено этим томом POSIX.1-2008, и логические записи данных не должны быть хранится на носителе.sizeполе должно игнорироваться при чтении.typeflagполя установлено любое другое значение, число логических записей, записанных после заголовка, должно быть без учета любой дроби в результате деления.( (size+ 511 ) / 512 )... и, конечно, учитывая также индивидуальный размер каждого заголовка, который является дополнительным блоком для каждого члена. Таким образом, вы можете пропустить чтение по чтению из заголовка в заголовок, пока не попадете на тот, который соответствует заголовку, для которого вы ищете, и тогда вам нужно будет проверить, описывает ли текущая запись ссылку на ваш файл или на текущий файл. , Это особенно актуально, потому что когда один и тот же файл добавляется в архив несколько раз, многие tars будут включать только заголовки ссылок, потому что данные фактического файла уже можно найти в другом месте в архиве.
Убедившись, что вам нужно применить свои вычисления к chksumполю и убедиться, что файл, который, по вашему мнению, у вас есть, в действительности является тем файлом, который вам нужен. tar«s chksumдовольно просто хотя-:
chksumПоле должно быть ISO / IEC 646: стандартная IRV представления восьмеричного значения простой суммы всех октетов в заголовке логической записи 1991. Каждый октет в заголовке должен рассматриваться как значение без знака. Эти значения должны быть добавлены к целому числу без знака, инициализированному нулю, точность которого составляет не менее 17 бит. При вычислении контрольной суммы chksumполе обрабатывается так, как если бы это были все символы <пробел> .Конечно, вам на самом деле не нужно ничего делать, потому что tarвы уже можете это сделать - вот что он делает - и поэтому вам, вероятно, следует просто использовать его для поиска в архиве и извлечения файла для вас. При этом он не будет действовать совсем иначе, чем если бы вы знали, о чем вы, за исключением того, что он, вероятно, сделает это лучше и быстрее, потому что это его работа. И вообще, зачем тебе?