Evite o caminho indesejado no arquivo Zip

49

Estou criando um script de shell para empacotar alguns arquivos. Estou compactando um diretório como este:

zip -r /Users/me/development/something/out.zip /Users/me/development/something/folder/

O problema é que o arquivo out.zip resultante possui todo o caminho do arquivo. Ou seja, quando descompactado, terá todo o caminho "/ Users / me / development / anotherthing /" nele. É possível evitar esses caminhos profundos ao colocar um diretório em um arquivo morto?

Quando executo o zip de dentro do diretório de destino, não tenho esse problema.

zip -r out.zip ./folder/

Nesse caso, não recebo todo o lixo. No entanto, o script em questão será chamado de qualquer lugar.

FWIW, estou usando o bash no Mac OS X 10.6.

jerwood
fonte

Respostas:

85

Seu script deve usar cdor pushde popdpara ir para o diretório que será a raiz do arquivo morto antes de emitir o zipcomando. Como você faz isso exatamente dependerá de como o script sabe o que deve ser compactado. Mas se você quiser / Users / me / development / something / folder compactado com caminhos internos de apenas ./pasta , precisará fazer o seguinte:

pushd /Users/me/development/something
zip -r /path/to/out.zip ./folder/
popd

Isso resultará no seu out.zip contendo os caminhos relativos que você deseja.

Se você precisar de ajuda para criar scripts, precisará nos mostrar seu script.

charlatão quixote
fonte
8
sem problemas. i fazer isso em one-liners na linha de comando o tempo todo, por exemplo: $ pushd /some/path ; do-something ; popd... ou mesmo com subshells:$ ( cd /some/path ; do-something )
quack quixote
1
@ ~ charlatão: +1 especialmente para a técnica sub-shell no comentário.
Jonathan Leffler
1
Embora usando &&em vez de ;é uma boa idéia para que o outro comando não é executado se o cdfalhou (erro de digitação ou outro problema):(cd /some/path && do-something)
Chris Johnsen
3
Não existe uma maneira de fazer isso sem especificar o caminho absoluto para o arquivo zip?
orange80
2
Por que você está jogando com o caminho? Por que não usar zip -j?
JWW
5

O problema é que o arquivo out.zip resultante possui todo o caminho do arquivo.
...
É possível evitar esses caminhos profundos ao colocar um diretório em um arquivo morto?

Sim. Use a -jopção com zip. -jé "junk the path". De acordo com a página do manual no zip :

Armazene apenas o nome de um arquivo salvo (junk the path) e não armazene nomes de diretório. Por padrão, o zip armazenará o caminho completo (relativo ao diretório atual).

Usar -jsignifica o seguinte comando:

zip -j myarchive.zip file1.txt dir1/file2.txt dir2/dir3/file3.txt ../file4.txt

Criará um arquivo que se parece com:

myarchive.zip
    |
    +-- file1.txt
    +-- file2.txt
    +-- file3.txt
    +-- file4.txt
jww
fonte
5
Isso também não inclui todos os caminhos, mesmo os que estão no diretório 'folder'? Eu acho que o OP só quer se livrar do caminho na linha de comando.
Peter Jaric
1
Pode não ser a resposta para esta pergunta, mas é o que eu preciso.
Aaron McMillin
1
Esta resposta assume incorretamente que o usuário deseja um zip plano. Essa é uma suposição incorreta e pode causar falha no script se dois arquivos em subpastas diferentes tiverem o mesmo nome.
Andrew Schwartz
1

Existe pushde popde $OLDPWD. Supondo que o $PWDis /Users/me/developmentdo:

pushd something/folder
zip -r $OLDPWD/something/out.zip *
popd

Agora o $PWDestá de volta a/Users/me/development

borodark
fonte