Я хочу просмотреть содержимое файла 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 )
... и, конечно, учитывая также индивидуальный размер каждого заголовка, который является дополнительным блоком для каждого члена. Таким образом, вы можете пропустить чтение по чтению из заголовка в заголовок, пока не попадете на тот, который соответствует заголовку, для которого вы ищете, и тогда вам нужно будет проверить, описывает ли текущая запись ссылку на ваш файл или на текущий файл. , Это особенно актуально, потому что когда один и тот же файл добавляется в архив несколько раз, многие tar
s будут включать только заголовки ссылок, потому что данные фактического файла уже можно найти в другом месте в архиве.
Убедившись, что вам нужно применить свои вычисления к chksum
полю и убедиться, что файл, который, по вашему мнению, у вас есть, в действительности является тем файлом, который вам нужен. tar
«s chksum
довольно просто хотя-:
chksum
Поле должно быть ISO / IEC 646: стандартная IRV представления восьмеричного значения простой суммы всех октетов в заголовке логической записи 1991. Каждый октет в заголовке должен рассматриваться как значение без знака. Эти значения должны быть добавлены к целому числу без знака, инициализированному нулю, точность которого составляет не менее 17 бит. При вычислении контрольной суммы chksum
поле обрабатывается так, как если бы это были все символы <пробел> .Конечно, вам на самом деле не нужно ничего делать, потому что tar
вы уже можете это сделать - вот что он делает - и поэтому вам, вероятно, следует просто использовать его для поиска в архиве и извлечения файла для вас. При этом он не будет действовать совсем иначе, чем если бы вы знали, о чем вы, за исключением того, что он, вероятно, сделает это лучше и быстрее, потому что это его работа. И вообще, зачем тебе?