Como escolher o nome do diretório durante o desempacotamento

125

Digamos que eu tenha o arquivo chamado ugly_name.tar, que quando extraído, se torna ugly_namediretório. Que comando eu posso usar para que o nome do diretório resultante seja pretty_name?

tshepang
fonte

Respostas:

172

Isso deve funcionar:

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

-Cmuda para o diretório especificado antes de descompactar (ou empacotar). --strip-componentsremove o número especificado de diretórios dos nomes de arquivos armazenados no arquivo morto.

Observe que isso não é realmente portátil. O tar do GNU e pelo menos alguns dos alcatrões do BSD têm a --strip-componentsopção, mas parece não existir em outras plataformas do tipo unix.

A maneira idiota de fazer isso funcionaria praticamente em todos os lugares.

tar xf ugly_name.tar && mv ugly_name pretty_name
Esteira
fonte
Acho que vou ficar com a versão mudo :)
phunehehe
28
@phunehehe: uma vantagem da versão inteligente é u não tem que saber de antemão o que o nome do diretório descompactado é
tshepang
2
Devo acrescentar que isso funciona por mais de "Pretty_name". Você também pode descompactar para um diretório específico dessa maneira. Exemplo:tar -xvf /tmp/backupfiles.tar -C /var/www/
General Redneck
2
Eu geralmente uso da maneira burra e uso caracteres curinga para o caso de não saber qual será o nome feio ou de não querer escrever. mv ugly-* pretty_name
David Grayson
1
O modo burro não funciona se já houver um ugly_namediretório. A propósito, a beleza está nos olhos de quem vê.
kmiklas 23/04
30

Com o GNU tar ≥1,16, use --transformpara aplicar uma transformação sed regexp a cada nome de arquivo (a transformação é aplicada no caminho completo do arquivo morto):

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

Se ugly_nameé o componente de nível superior de todos os nomes de arquivos no arquivo morto, você não precisa se preocupar com a correspondência precisa:

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

Se você não souber o nome do diretório de nível superior, ainda poderá usar esse método, embora prefira --strip-components.

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

Com paxo utilitário de arquivamento POSIX, use a -sopção, que aceita uma expressão de substituição semelhante 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
fonte
9

Usa isto :

tar -xvf ugly_name.tar
mv ugly_name pretty_name
Rupesh Mande
fonte
9
Você pode preferir usar o &&operador de lista entre esses dois comandos, para que o segundo seja executado apenas se o primeiro tiver êxito.
manatwork
1
Isso pode ter consequências indesejáveis ​​se um diretório ugly_namejá existir.
Drew Dormann
7

Maneira mais simples

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1
marquicus
fonte
(1) Essa claramente não é a maneira mais simples, pois o smac89 postou uma resposta apresentando --one-top-level=pretty_namesem --strip-components 1. (2) Por outro lado, a resposta aceita (postada por Mat) aparece --strip-components 1sem --one-top-level=pretty_name. (3) Você pode explicar por que sua resposta, combinando essas opções, é melhor do que qualquer uma das mais antigas? Por favor, não responda nos comentários; edite  sua resposta para torná-la mais clara e completa.
G-Man
talvez um exemplo real possa ajudá-lo a esclarecer: `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
Esta resposta é mais elegante do que aquela com mais votos .
KaiserKatze
@ O G-Man --strip-component 1é necessário, com o método mkdirou --strip-components 1, caso contrário, você simplesmente obtém pretty_name/ugly_name/.
davidA 24/09
Esta é realmente a maneira mais simples
smac89 25/09
2

No askUbuntu, esta resposta funcionou para mim:

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

`--um nível superior [= dir] '

Diz ao tar para criar um novo diretório abaixo do diretório de extração (ou o passado para `-C ') e usá-lo para proteger-se contra tarbombs. Na ausência de argumento dir, o nome do novo diretório será igual ao nome base do arquivo morto (nome do arquivo menos o sufixo do arquivo morto, se reconhecido). Qualquer nome de membro que não comece com esse nome de diretório (após transformações de `--transform 'e` --strip-components') será prefixado com ele. Os sufixos de nome de arquivo reconhecidos são `.tar 'e qualquer sufixo de compactação reconhecível por See -auto-compress .


Atualizar

Conforme apontado nos comentários , esse método não funciona para arquivos formados corretamente, no entanto, como mostra outra resposta , você deve adicionar --strip-components 1para que isso realmente funcione. Eu testei com esta nova opção e funciona tanto para arquivos com um nome de nível superior quanto para aqueles sem.

smac89
fonte
O problema disso é que ele não renomeia o diretório de nível superior, mas cria um novo nível, chamado pretty_name, com o diretório de nível superior original dentro dele. Por exemplo, se você tar xzf ugly_name.tgzcriar um diretório chamado ugly_name/, o comando que você forneceu criará pretty_name/ugly_name/.
davidA 24/09
1
@davidA Bom ponto. Atualizei minha resposta para incluir uma correção para isso
smac89