Назад | Перейти на главную страницу

Есть ли быстрый способ получить самый последний файл в большом TAR?

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

Нет, к сожалению, нет. Из Википедия

Еще одна слабость формата tar по сравнению с другими форматами архивов заключается в отсутствии централизованного расположения информации о содержимом файла (своего рода «оглавление»). Таким образом, чтобы перечислить имена файлов, находящихся в архиве, нужно прочитать весь архив и найти места, откуда файлы начинаются. Кроме того, чтобы извлечь один небольшой файл из архива, вместо того, чтобы найти смещение в таблице и перейти непосредственно в это место, как и другие форматы архивов, с помощью tar, нужно прочитать весь архив в поисках места. где начинается нужный файл. Для больших архивов tar это приводит к значительному снижению производительности, делая архивы tar непригодными для ситуаций, которые часто требуют произвольного доступа к отдельным файлам.

Мы можем эффективно искать последний файл в архиве, если tar создается в доступном для поиска хранилище, то есть на жестких дисках, а не на ленте. используйте параметр GNU tar -n или --seek. ( посмотри это Страница параметров GNU tar ) скажем, например, файл, который хранится последним с именем last_file.txt, вы можете использовать следующую команду

tar -nxvf <your_archive> last_file.txt

Что бы просто извлечь last_file.txt. поскольку формат tar содержит размер каждого файла в заголовке, можно эффективно пропустить весь файл, используя системный вызов seek (см. формат файла tar )

Чтобы перечислить только все файлы в большом архиве, используйте

tar -ntvf <your_archive>

Да; если вы знаете размер файла, который вам нужен, вы можете скопировать конец tar с помощью dd skip. или если вы хотите прочитать весь файл один раз для последующего быстрого произвольного доступа, вы можете создать индекс с помощью:

tar -tRvf "$TAR"

Пример сценария:

#!/bin/bash

#
# tar_extract_via_index.sh
#

TAR="$1"
RE="$2"

if [ ! -f "$TAR" ] ; then
    echo "Not a file $TAR"
    exit 1
fi
if [ "$RE" == "" ] ; then
    echo "Expecting a $RE"
    exit 2
fi
if [ ! -f "$TAR".index ] ; then
    tar -tRvf "$TAR" > "$TAR".index
fi
MATCH="$(grep -P "$RE" "$TAR".index)"
if [ "$(echo "$MATCH" | grep -c .)" != "1" ] ; then
    echo "Multipule matches:"
    echo "$MATCH" | perl -pe 's/^/\t/g' >&2
    exit 3
fi
FILE="$( echo "$MATCH" | perl -pe 's/.* \.\///g;s/.*\///g')"
SKIP="$( echo "$MATCH" | perl -pe 's/:.*//g;s/.* //g')"
COUNT="$(echo "$MATCH" | perl -pe 's/\.\/.*//g;s/.*\/[^ ]+ +//g;s/ .*//g')"
SKIP="$(echo "($SKIP+1)*512" | bc)"
dd if="$TAR" bs=1 status=none skip=$SKIP count=$COUNT of="$FILE"
echo "$FILE"