Самый простой способ - скопировать весь архив; Я полагаю, вы не хотите этого делать, потому что он слишком большой.
Обычные инструменты командной строки ( tar
, pax
) не поддерживают копирование членов архива в другой архив.
Если вам не нужно сохранять права собственности, я бы предложил использовать файловые системы FUSE . Вы можете использовать archivemount для монтирования архива как файловой системы; сделайте это для исходного архива и запустите tar на смонтированной файловой системе.
archivemount some.tar.gz mnt
cd mnt
tar -cz subdir | ssh example.com tar -xz
fusermount -u mnt
В качестве альтернативы вы можете использовать AVFS :
mountavfs
cd ~/.avfs$PWD/some.tar.gz\#
tar -cz subdir | ssh example.com tar -xz
Кроме того, вы можете запустить tar
исходный архив и распаковать его на удаленный компьютер через SSHFS .
sshfs example.com: mnt
cd mnt
tar -xf /path/to/some.tar.gz subdir
fusermount -u mnt
Однако все эти методы громоздки, если вам нужно сохранить право собственности. Все они включают извлечение в файл на локальном компьютере, поэтому владельцем этого файла должно быть предполагаемое удаленное владение. Это требует запуска от имени пользователя root и может не дать ожидаемого результата, если файлы принадлежат учетным записям, чьи имена или идентификаторы отличаются на локальном компьютере и на удаленном хосте.
tarfile
Библиотека Python предоставляет довольно простой способ манипулирования членами tar, поэтому вы можете перемещать их из одного файла tar в другой. Он поддерживает стандартные форматы POSIX (ustar, pax), а также некоторые расширения GNU. Вот непроверенный скрипт Python, который считывает файл tar (возможно, сжатый с помощью gzip или bzip2) на свой стандартный ввод и записывает файл tar, сжатый с помощью bzip2, на свой стандартный вывод. Члены из источника копируются, если они начинаются с аргумента, переданного сценарию.
#!/usr/bin/env python2
import sys, tarfile
source = tarfile.open(fileobj=sys.stdin)
destination = tarfile.open(fileobj=sys.stdout, mode='w:bz2')
for info in source:
if info.name.startswith(sys.argv[1]):
destination.addfile(info)
destination.close()
Быть призванным как
tar_filter <some.tar.gz subdir/ | ssh example.com tar -xj
@original.tar
подход возможен с bsdtar. Кажется, работает с расширенными атрибутами и сжатием, а также</var/cache/pacman/pkg/libuv-1.7.0-1-x86_64.pkg.tar.xz bsdtar -czf - --include='usr/share/*' @- | tar tvz
(и по какой-то причине пустой выбор производит серию нулевых байтов, но для меня это не является большой проблемой).