Pasta Zip sem incluir o caminho para a pasta e requer apenas um argumento

3

Estou tentando criar uma função zip que fará todas as etapas que normalmente faço ao compactar um arquivo ou uma pasta. Digamos que meu diretório atual seja ~ e eu queira zipar uma pasta chamada Folder1 , cujo caminho do arquivo é ~/Folder2/Folder1 .

Emitindo

cd ~/Folder2 && zip -r Folder1 Folder1 && cd -

faz exatamente o que eu quero. Ou seja, ele fecha de modo que a saída Folder1.zip não contenha pastas que levem à pasta que estou compactando (ou seja, /home/user/Folder2 ), feche recursivamente e receba o primeiro argumento do CEP com o nome exato como o arquivo ou pasta que estou compactando ( Folder1.zip ).

Então eu quero fazer uma função no meu .zshrc algo parecido com

coolerzip() { cd /path/to/file && zip -r file file && cd - }

onde ele precisa apenas receber um argumento, que neste caso, será ~/Folder2/Folder1 . Então Folder1 será o nome para file s em coolerzip , e eu vou cd para ~/Folder2 então Folder1 está no meu diretório atual antes de zipar. Existe alguma maneira que eu possa conseguir isso para que coolerzip requer apenas um argumento em vez de três?

    
por Dustin Tran 14.08.2013 / 12:28

2 respostas

0

O argumento da função é $1 .

Você pode usar modificadores de expansão de histórico para extrair a parte do diretório e o último componente do caminho: se o argumento for ~/directory2/directory1 , então $1:h será ~/directory2 e $1:t será directory1 . (Mnemônico: h ead e t ail.)

Use parênteses em vez de chaves ao redor do corpo da função. Desta forma, o corpo da função é executado em um subshell (um processo de shell separado), e as atribuições de variáveis, mudanças de diretório e assim por diante afetam apenas a sub-camada.

coolerzip () (
    cd $1:h &&
    zip -r $2:h.zip $2:h
)

Outras shells não possuem modificadores de expansão de histórico, então você precisa de algo diferente para analisar o argumento. Para o nome do arquivo, ${1##*/} remove todos os componentes principais do diretório; no entanto, isso não funciona se houver uma barra no parâmetro, enquanto "$(basename -- "$1")" funciona nesse caso. Para os diretórios principais, use $(dirname -- "$1") . Note que em shells que não sejam zsh, você precisa colocar aspas duplas em torno das substituições de variáveis .

coolerzip () (
    name="$(basename -- "$1")"
    cd "$(dirname -- "$1")" &&
    zip -r "$name.zip" "$name"
)
    
por 15.08.2013 / 02:21
1

Eu não sou um usuário zsh, mas o seguinte funciona no bash e eu não acho que ele esteja usando nenhum bashismo em particular, então isso deve fazer o trabalho:

coolerzip() { cd "${1%/*}" && zip -r "${1##*/}" "${1##*/}" && cd -; }

$1 é um parâmetro posicional; em um script ou uma função, referenciará o argumento primeiro dado ao script ou função na linha de comando. Você também pode usar $2 e assim por diante, até $9 . $0 fornece o nome do script ou função (o argumento zeroth), $@ fornece todos os argumentos, exceto zeroth e $# fornece o número de argumentos (novamente, excluindo o zeroth). As coisas se comportam de maneira um pouco diferente se você chamar sh -c (ou qualquer shell) da linha de comando, mas não vou entrar aqui.

${1%/*} retorna o valor de $1 com a menor coincidência do padrão de glob */ removida (se você quiser a correspondência mais longa no final, use %% ) - - por isso, tira a parte final do caminho que você alimenta a função. ${1##*/} retira a correspondência mais longa do padrão */ no início de $1 (para a correspondência mais curta no início, use um único # ).

A função acima é um pouco frágil; ele será quebrado se houver alguma barra no argumento (por exemplo, ~/folder1/folder2/ ). Ele será quebrado de maneira diferente se o argumento for um nome de diretório único que não contenha barras. Uma maneira fácil de contornar isso é usar o comando readlink para retornar o caminho completo do argumento de entrada (e também remover qualquer barra final, pelo menos no meu sistema Ubuntu).

coolerzip() { a="$(readlink -f "$1")"; cd "${a%/*}" && zip -r "${a##*/}" "${a##*/}" && cd -; }
    
por 14.08.2013 / 13:02