Просмотр файла в архиве tar без его распаковки

16

Я хочу просмотреть содержимое файла tarred, не распаковывая его, Сценарий: у меня есть .tar, а внутри есть файл с именем ./x/y.txt. Я хочу, чтобы просмотреть содержание y.txtбез фактического извлечения a.tar.

Ramji
источник
Если вы используете Emacs, вы можете просто открыть в нем тарбол.
Кудит
Э-э, чтобы его увидеть, нужно его извлечь. Я предполагаю, что вы имеете в виду "без записи в файл"?
Тоби Спейт

Ответы:

20

Вероятно, это специфическая опция GNU, но вы можете использовать -Oили --to-stdoutдля извлечения файлов в стандартный вывод

$ tar -axf file.tgz foo/bar -O
fredtantini
источник
Ах работает, но мне не удалось напечатать вывод на новых строках. ех; tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Oнапример, когда совпадают многие файлы *read_this_file*. Все печатается на одной строке. Из того man, что я нашел --to-command. так что прохождение --to-command="echo '' && cat"- это немного чёрной магии, но это работает: D
GabLeRoux
Просто это нужно в ответе:$ tar -axf file.tgz foo/bar -O
user1742529
12

Это печатает содержимое ./x/y.txt из a.tar в STDOUT.

tar xfO a.tar ./x/y.txt

Toni
источник
2
подсказка: это заглавная буква "о", а не ноль.
Юбер Гжесковяк
4

Это просто как

less  a.tar:./x/y.txt

Этот магический трюк работает, если вы lesspipeустановили и если переменная env LESSOPENопределена как | /usr/bin/lesspipe.sh %sожидаемая, если вы правильно установили lesspipe .

солнцестояние
источник
Это потрясающий сценарий - но есть больше, чем один. Насколько я понимаю, этоlesspipe.sh должно быть предпочтительнее.
mikeserv
Будет ли это работать на сжатых архивах?
Тердон
Должно. Но я только что обнаружил, что это не работает в Ubuntu. Пойди разберись. Они сломали или удалили функцию. Вы по-прежнему можете просматривать список архивов с меньшим, но не с содержимым файла :-(
solsTiCe
2

Да, но это вопрос о содержании файла в 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-байтовых блоках:

  • USTAR
    • Формат tarобмена; смотрите раздел РАСШИРЕННОЕ ОПИСАНИЕ . Размер блока по умолчанию для этого формата для символьных специальных архивных файлов должен быть 10240 . Реализации должны поддерживать все значения размера блока, меньшие или равные 32256 , кратные 512 .

Поэтому, если вы работаете с tarфайлом, который может содержать файлы, которые могут содержать произвольные двоичные данные, вам придется пропустить файл алгоритмически и в соответствии с типом файла. В спецификации сказано:

  • sizeПоле размер файла в октетах.
    • Если в typeflagполе указано, что файл должен иметь тип 1 ( ссылка ) или 2 ( символьная ссылка ) , sizeполе должно быть указано как ноль.
    • Если в typeflagполе задано указание файла типа 5 ( каталог ) , это sizeполе следует интерпретировать, как описано в определении этого типа записи.
    • Логические записи данных не сохраняются для типов 1 , 2 или 5 .
    • Если для typeflagполя установлено значение 3 ( специальный символьный файл) , 4 ( специальный блочный файл) или 6 ( FIFO ) , значение sizeполя не определено этим томом POSIX.1-2008, и логические записи данных не должны быть хранится на носителе.
    • Кроме того, для типа 6 , то sizeполе должно игнорироваться при чтении.
  • Если для typeflagполя установлено любое другое значение, число логических записей, записанных после заголовка, должно быть без учета любой дроби в результате деления.( (size+ 511 ) / 512 )

... и, конечно, учитывая также индивидуальный размер каждого заголовка, который является дополнительным блоком для каждого члена. Таким образом, вы можете пропустить чтение по чтению из заголовка в заголовок, пока не попадете на тот, который соответствует заголовку, для которого вы ищете, и тогда вам нужно будет проверить, описывает ли текущая запись ссылку на ваш файл или на текущий файл. , Это особенно актуально, потому что когда один и тот же файл добавляется в архив несколько раз, многие tars будут включать только заголовки ссылок, потому что данные фактического файла уже можно найти в другом месте в архиве.

Убедившись, что вам нужно применить свои вычисления к chksumполю и убедиться, что файл, который, по вашему мнению, у вас есть, в действительности является тем файлом, который вам нужен. tar«s chksumдовольно просто хотя-:

  • CKSUM
    • chksumПоле должно быть ISO / IEC 646: стандартная IRV представления восьмеричного значения простой суммы всех октетов в заголовке логической записи 1991. Каждый октет в заголовке должен рассматриваться как значение без знака. Эти значения должны быть добавлены к целому числу без знака, инициализированному нулю, точность которого составляет не менее 17 бит. При вычислении контрольной суммы chksumполе обрабатывается так, как если бы это были все символы <пробел> .

Конечно, вам на самом деле не нужно ничего делать, потому что tarвы уже можете это сделать - вот что он делает - и поэтому вам, вероятно, следует просто использовать его для поиска в архиве и извлечения файла для вас. При этом он не будет действовать совсем иначе, чем если бы вы знали, о чем вы, за исключением того, что он, вероятно, сделает это лучше и быстрее, потому что это его работа. И вообще, зачем тебе?

mikeserv
источник
0

Вы можете использовать эту строку

tar -axf a.tar -O
tachomi
источник
3
Это покажет любой файл в tar, а не только, y.txtи из вопроса OP не ясно, что это единственный файл в tar.
Anthon