La forma más fácil sería copiar todo el archivo; Supongo que no quieres hacer eso porque es demasiado grande.
Las herramientas de línea de comandos habituales ( tar
, pax
) no admiten copiar miembros de un archivo a otro archivo.
Si no necesita preservar la propiedad, le sugiero que use los sistemas de archivos FUSE . Puede usar archivemount para montar un archivo como sistema de archivos; haga esto para el archivo fuente y ejecute tar en el sistema de archivos montado.
archivemount some.tar.gz mnt
cd mnt
tar -cz subdir | ssh example.com tar -xz
fusermount -u mnt
Alternativamente, puede usar AVFS :
mountavfs
cd ~/.avfs$PWD/some.tar.gz\#
tar -cz subdir | ssh example.com tar -xz
Alternativamente, puede ejecutar tar
el archivo original y extraerlo a la máquina remota a través de SSHFS .
sshfs example.com: mnt
cd mnt
tar -xf /path/to/some.tar.gz subdir
fusermount -u mnt
Sin embargo, todos estos métodos son engorrosos si necesita preservar la propiedad. Todos implican extraer a un archivo en la máquina local, por lo que la propiedad de este archivo tendrá que ser la propiedad remota prevista . Esto requiere ejecutarse como root y puede no dar el resultado deseado si los archivos son propiedad de cuentas que tienen nombres o ID que difieren entre la máquina local y el host remoto.
La tarfile
biblioteca de Python proporciona una forma bastante fácil de manipular miembros tar, por lo que puede barajarlos de un archivo tar a otro. Admite formatos estándar POSIX (ustar, pax), así como algunas extensiones GNU. Aquí hay un script Python no probado que lee un archivo tar (posiblemente comprimido con gzip o bzip2) en su entrada estándar y escribe un archivo tar comprimido con bzip2 en su salida estándar. Los miembros de la fuente se copian si comienzan con el argumento pasado al script.
#!/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()
Para ser invocado como
tar_filter <some.tar.gz subdir/ | ssh example.com tar -xj
@original.tar
enfoque era posible con bsdtar. Parece funcionar también con atributos extendidos y compresión</var/cache/pacman/pkg/libuv-1.7.0-1-x86_64.pkg.tar.xz bsdtar -czf - --include='usr/share/*' @- | tar tvz
(y, por alguna razón, una selección vacía produce una serie de cero bytes, pero eso no es un problema importante para mí).