4 votos

Desempaquetar un tarball a través de un terminal como el Finder

Si tengo un .tar o .tgz o .tbz en mi escritorio, y hago doble clic en él, me aparece la carpeta que se comprimió, perfectamente descomprimida, justo al lado del archivo. Tal y como cabría esperar.

Cuando intento descomprimir un elemento alquitranado a través del tar la salida que obtengo tiene la ruta completa del archivo comprimido original.

Así, por ejemplo, si hago un .tbz de una carpeta en mi escritorio llamada "foo", y luego lo descomprimo mediante tar -xf foo.tbz ~/Desktop/foo lo que obtengo es: /Users/[user]/Desktop/foo/Users/[user]/desktop/foo/bar.txt

¿Hay alguna bandera mágica en tar que no estoy viendo? He buscado en Google un "cómo" tras otro que te da una sencilla tar para extraer un archivo, pero todas las direcciones que veo me dan el resultado no deseado con directores de resultados largos, innecesarios y super anidados.

2voto

Phill Puntos 126

La opción que busca es --strip-components (de man tar ):

-componentes de la franja cuenta

(sólo en modo x) Elimina el número especificado de elementos iniciales de la ruta. Los nombres de ruta con menos elementos serán omitidos silenciosamente.

Pero no es 100% equivalente a la forma en que funciona el Finder: todavía necesita saber la profundidad del directorio para despojarse.

Afortunadamente, se puede calcular con este comando:

while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf <tar archive name> | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1

Ya que tiene que reemplazar <tar archive name> con el nombre de su archivo tar, no es tan conveniente como simplemente hacer doble clic en el Finder, pero puede ser útil en Bash scripts.

Si el archivo tar contiene varios archivos en diferentes rutas, el comando anterior calcula la profundidad máxima del directorio común:

tar archive contents          =>      extracted files using --strip-components

dir1/dir2/file1               =>      file1
dir1/dir2/dir3/file2          =>      dir3/file2
dir1/dir2/dir3/dir4/file3     =>      dir3/dir4/file3

Por ejemplo, si creas un archivo tar como este:

mkdir -p a/b/c/d/e/f
touch a/b/c/d/e/f/myfile1
touch a/b/c/d/e/myfile2
tar cvf file.tar a

para que:

tar tf file.tar
a/
a/b/
a/b/c/
a/b/c/d/
a/b/c/d/e/
a/b/c/d/e/f/
a/b/c/d/e/myfile1
a/b/c/d/e/f/myfile2

puede extraer todos los archivos (con la profundidad de directorio más corta) de la siguiente manera:

  1. Calcular la profundidad máxima del directorio común:

    while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1

    El comando devuelve 5 .

  2. Ejecutar tar pasando el resultado del comando anterior a --strip-components :

    tar xvf file.tar --strip-components 5
    x f/
    x myfile1
    x f/myfile2

En lugar de ejecutar dos comandos, si su shell es bash o zsh puede utilizar $() para pasar el resultado directamente a --strip-components :

tar xvf file.tar --strip-components $(while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1)
x f/
x myfile1
x f/myfile2

Este comando también trata adecuadamente el caso de un archivo tar sin jerarquía de directorios:

touch myfile3
tar cvf file2.tar myfile3
tar xvf file2.tar --strip-components $(while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file2.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1)
x myfile3

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X