Cómo elegir el nombre del directorio durante la descompresión

125

Digamos que tengo un nombre de archivo ugly_name.tar, que cuando se extrae, se convierte en ugly_namedirectorio. ¿Qué comando puedo usar para que el nombre del directorio resultante sea en su pretty_namelugar?

tshepang
fuente

Respuestas:

172

Esto debería funcionar:

mkdir pretty_name && tar xf ugly_name.tar -C pretty_name --strip-components 1

-Ccambia al directorio especificado antes de desempaquetar (o empacar). --strip-componentselimina el número especificado de directorios de los nombres de archivo almacenados en el archivo.

Tenga en cuenta que esto no es realmente portátil. El alquitrán GNU y al menos algunos de los alquitranes BSD tienen la --strip-componentsopción, pero no parece existir en otras plataformas similares a Unix.

Sin embargo, la forma tonta de hacerlo funcionaría prácticamente en todas partes.

tar xf ugly_name.tar && mv ugly_name pretty_name
Estera
fuente
Creo que me quedaré con la versión tonta :)
phunehehe
28
@phunehehe: una ventaja de la versión inteligente es que no tiene que saber de antemano cuál es el nombre del directorio sin
marcar
2
¿Puedo agregar que esto funciona para más de "Pretty_name". También puede descomprimir en un directorio específico de esta manera. Ejemplo:tar -xvf /tmp/backupfiles.tar -C /var/www/
General Redneck el
2
Por lo general, uso la forma tonta, y uso comodines en caso de que no sepa cuál será el nombre feo o si no quiero escribirlo. mv ugly-* pretty_name
David Grayson
1
La manera tonta no funciona si ya hay un ugly_namedirectorio. Por cierto, la belleza está en el ojo del espectador.
kmiklas
30

Con GNU tar ≥1.16, use --transformpara aplicar una transformación sed regexp a cada nombre de archivo (la transformación se aplica en la ruta completa en el archivo):

tar xf foo.tar --transform 's!^ugly_name\($\|/\)!pretty_name\1!'

Si ugly_namees el componente de nivel superior de todos los nombres de archivo en el archivo, no necesita molestarse con una coincidencia precisa:

tar xf foo.tar --transform 's/ugly_name/pretty_name/'

Si no conoce el nombre del directorio de nivel superior, aún puede usar este método, aunque puede preferirlo --strip-components.

tar xf foo.tar --transform 's!^[^/]\+\($\|/\)!pretty_name\1!'

Con paxla utilidad de archivo POSIX, use la -sopción, que toma una expresión de reemplazo similar a sed como argumento.

pax -rf foo.tar -s '!^ugly_name\($\|/\)!pretty_name\1!'
pax -rf foo.tar -s '/ugly_name/pretty_name/'
pax -rf foo.tar -s '!^[^/]\+\($\|/\)!pretty_name\1!'
Gilles
fuente
9

Utilizar este :

tar -xvf ugly_name.tar
mv ugly_name pretty_name
Rupesh Mande
fuente
99
Es posible que prefiera usar el &&operador de lista entre esos dos comandos, de modo que el segundo se ejecute solo si el primero tuvo éxito.
manatwork
1
Esto podría tener consecuencias no deseadas si ugly_nameya existe un directorio .
Drew Dormann
7

La manera más simple

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1
marquicus
fuente
(1) Claramente, esta no es la forma más simple, ya que smac89 publicó una respuesta que presenta --one-top-level=pretty_namesin --strip-components 1. (2) Por el contrario, la respuesta aceptada (publicada por Mat) presenta --strip-components 1sin --one-top-level=pretty_name. (3) ¿Puede explicar por qué su respuesta, combinando estas opciones, es mejor que cualquiera de las anteriores? Por favor no responda en los comentarios; edite  su respuesta para que sea más clara y completa.
G-Man
quizás un ejemplo real pueda ayudarlo a aclarar: `wget dev.mysql.com/get/Downloads/MySQL-5.7/… tar xvf mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz --one-top -level = mysql57 --strip-components 1 `
marquicus el
Esta respuesta es más elegante que la que tiene más votos .
KaiserKatze
--strip-component 1Se requiere @ G-Man , ya sea con el método mkdiro --strip-components 1, de lo contrario, solo obtendrá pretty_name/ugly_name/.
davidA
Esta es de hecho la forma más simple
smac89
2

Desde askUbuntu, esta respuesta funcionó para mí:

tar zxvf ugly_name.tgz --one-top-level=pretty_name

`--un nivel superior [= dir] '

Le dice a tar que cree un nuevo directorio debajo del directorio de extracción (o el que se pasó a '-C') y lo use para protegerse de las tarbombas. En ausencia de un argumento dir, el nombre del nuevo directorio será igual al nombre base del archivo (nombre del archivo menos el sufijo del archivo, si se reconoce). Cualquier nombre de miembro que no comience con ese nombre de directorio (después de las transformaciones de `--transform 'y` --strip-components') tendrá el prefijo. Los sufijos de nombre de archivo reconocidos son `.tar ', y cualquier sufijo de compresión reconocible por See -auto-compress .


Actualizar

Como se señaló en los comentarios , este método no funciona para archivos que están formados correctamente, sin embargo, como muestra otra respuesta , debe agregar --strip-components 1para que esto realmente funcione. He probado con esta nueva opción y funciona tanto para archivos con un nombre de nivel superior como sin ellos.

smac89
fuente
El problema con esto es que no cambia el nombre del directorio de nivel superior, sino que crea un nuevo nivel, llamado pretty_name, con el directorio original de nivel superior dentro de eso. Por ejemplo, si tar xzf ugly_name.tgzcrearía un directorio llamado ugly_name/, se crearía el comando que ha proporcionado pretty_name/ugly_name/.
davidA
1
@davidA Buen punto. He actualizado mi respuesta para incluir una solución para esto
smac89