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:
-
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
.
-
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