Como posso saber se “unzip” criará uma única pasta antes do tempo?

4

Um cenário comum é ter um arquivo zip em um diretório com outro trabalho:

me@work ~/my_working_folder $ ls
downloaded.zip  workfile1  workfile2  workfile3

Eu quero descompactar o downloaded.zip , mas não sei se vai fazer uma bagunça ou se cria um diretório próprio. Minha solução alternativa é criar uma pasta temporária e descompactá-la:

me@work ~/my_working_folder $ mkdir temp && cp downloaded.zip temp && cd temp
me@work ~/my_working_folder/temp $ ls
downloaded.zip
me@work ~/my_working_folder/temp $ unzip downloaded.zip 
Archive:  downloaded.zip
   creating: nice_folder/

Isso impede que my_working_folder seja preenchido com muitos conteúdos de arquivos zip.

A minha pergunta é: Existe uma maneira melhor de determinar se um arquivo zip contém apenas uma pasta antes de descompactar?

    
por user1717828 20.10.2016 / 17:25

3 respostas

2

Do manual ...

[-d exdir]

An optional directory to which to extract files. By default, all files and subdirectories are recreated in the current directory; the -d option allows extraction in an arbitrary directory (always assuming one has permission to write to the directory). This option need not appear at the end of the command line; it is also accepted before the zipfile specification (with the normal options), immediately after the zipfile specification, or between the file(s) and the -x option. The option and directory may be concatenated without any white space between them, but note that this may cause normal shell behavior to be suppressed. In particular, -d ~ (tilde) is expanded by Unix C shells into the name of the user's home directory, but -d~ is treated as a literal subdirectory ~ of the current directory.

Então ...

unzip -d new_dir zipfile.zip

Isso cria um diretório, new_dir, e extrai o arquivo dentro dele, o que evita a possível confusão toda vez, mesmo sem procurar primeiro. Também é muito útil consultar man unzip . Mais ajuda para páginas de manual .

    
por 20.10.2016 / 22:29
5

Bem, você poderia apenas extrair um subdiretório incondicionalmente e se livrar dele depois, se ele acabar contendo apenas um único item.

Mas por que escolher um solução sã e fácil (cortesia de ilkkachu ), quando você pode usar awk em vez disso? :)

sunzip ()
{
    if [ $# -ne 1 -o ! -f "$1" ]
    then
        printf '%s\n' "Expected a filename as the first (and only) argument. Aborting."
        return 1
    fi

    extract_dir="."

    # Strip the leading and trailing information about the zip file (leaving
    # only the lines with filenames), then check to make sure *all* filenames
    # contain a /.
    # If any file doesn't contain a / (i.e. is not located in a directory or is
    # a directory itself), exit with a failure code to trigger creating a new
    # directory for the extraction.
    if ! unzip -l "$1" | tail -n +4 | head -n -2 | awk 'BEGIN {lastprefix = ""} {if (match($4, /[^/]+/)) {prefix=substr($4, RSTART, RLENGTH); if (lastprefix != "" && prefix != lastprefix) {exit 1}; lastprefix=prefix}}'
    then
        extract_dir="${1%.zip}"
    fi

    unzip -d "$extract_dir" "$1"
}

Quick'n'dirty. Funciona com unzip v6.0 do InfoZIP.
Você pode querer adaptá-lo às suas necessidades, por exemplo para aceitar ou usar automaticamente parâmetros adicionais para unzip ou para usar um nome diferente para o subdiretório de extração (que é atualmente determinado pelo nome do arquivo zip ).

Ah, e notei que essa solução alternativa lida corretamente com as duas situações mais comuns (1. O arquivo ZIP contém um único diretório com conteúdo, 2. O arquivo ZIP contém muitos arquivos e / ou diretórios individuais), mas não • crie um subdiretório quando a raiz do arquivo ZIP contiver vários diretórios, mas nenhum arquivo…

Editar: corrigido. O script awk agora armazena o primeiro componente ("prefixo") de cada caminho contido no arquivo ZIP, e aborta assim que detecta um prefixo que difere do anterior. Isso captura vários arquivos e vários diretórios (já que ambos são obrigados a ter nomes diferentes), ignorando os arquivos ZIP onde tudo está contido no mesmo subdiretório.

    
por 20.10.2016 / 17:49
2

Você pode usar meu script usando mv .

mkdir downloaded

mv downloaded.zip downloaded && cd downloaded

unzip downloaded.zip && cd

Você criará uma pasta (baixada) e a descompactará na pasta criada.

    
por 20.10.2016 / 22:51

Tags