Como compactar arquivos como uma pasta
Tenho uma estrutura de arquivo semelhante a esta:
- root_folder_with_bad_name
- file1
- file2
- file3
Preciso obter um arquivo zip com esta estrutura:
- archive.zip
- some_folder
- file1
- file2
- file3
Não sei o nome dos arquivos root_folder, então não posso simplesmente fazer isso:
zip archive.zip some_root_folder_name
Eu quero ser capaz de compactar os arquivos dentro dessa pasta. Como eu posso fazer isso?
Respostas
Você parece querer armazenar arquivos em ziparquivos com nomes ou caminhos diferentes dos originais. Além de remover o caminho inteiramente, a modificação de caminhos ou nomes de ziparquivos em arquivos não parece ser possível com os utilitários comumente disponíveis.
Como alternativa, você pode criar a estrutura de diretório desejada em uma pasta temporária usando links físicos.
(Não tenho ideia do motivo pelo qual as pessoas estão se referindo a tare gzip. Eles não são relevantes, pois você afirma especificamente que deseja ziparquivos.)
Você pode criar uma hierarquia de diretório temporário com o nome da pasta de arquivo de destino, compactá-la e removê-la.
Isso funciona bash, pressupondo que não haja um diretório (ou arquivo) já nomeado archiveno diretório atual
(
shopt -s extglob
mkdir archive &&
cp -al !(archive) archive &&
zip -r archive.zip archive
rm -rf archive
)
Observe que a nova hierarquia de diretório é vinculada em vez de copiada, então (a) é rápida, (b) não ocupa nenhum espaço extra significativo em disco.
Exemplo trabalhado
# Set up the files in a directory
mkdir secret_name; touch secret_name/file{1,2,3}
cd secret_name/
# Now create the archive
( shopt -s extglob; mkdir archive && cp -al !(archive) archive/ && zip -r archive.zip archive; rm -rf archive )
# List the archive
unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
0 2020-10-16 19:21 archive/
0 2020-10-16 19:12 archive/file2
0 2020-10-16 19:12 archive/file3
0 2020-10-16 19:12 archive/file1
--------- -------
0 4 files
Você pode usar o libarchive bsdtare sua -sopção para editar os caminhos dos arquivos adicionados ao arquivo:
$ ls file1 file2 file3 $ bsdtar --format=zip -'s|^\.|some_folder|' -cf ../file.zip .
$ unzip -l ../file.zip
Archive: ../file.zip
Length Date Time Name
--------- ---------- ----- ----
0 2020-10-16 21:15 some_folder/
0 2020-10-16 21:15 some_folder/file1
0 2020-10-16 21:15 some_folder/file3
0 2020-10-16 21:15 some_folder/file2
--------- -------
0 4 files
Também parece funcionar usando um link simbólico, sem copiar arquivos.
> ls old_parent/
file1 file2
> ln -s old_parent new_parent
> zip -r archive.zip new_parent
adding: new_parent/ (stored 0%)
adding: new_parent/file2 (deflated 22%)
adding: new_parent/file1 (deflated 38%)
> unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
0 2020-10-16 22:48 new_parent/
50 2020-10-14 08:18 new_parent/file2
348 2020-10-16 13:58 new_parent/file1
--------- -------
398 3 files
> rm new_parent