Como obter “glob atual” em zsh

2

Eu quero fazer algo como:

$ convert [a,b,c,d,e].png -resize 50% <current_match>_half.png

Como posso fazer isso? Existe alguma variável que armazena a correspondência atual? Não encontrei nada nos documentos, mas talvez esteja procurando as palavras-chave erradas.

Eu achei que talvez pudesse fazer isso com xargs , mas também não consegui resolver isso.

    
por potatohammock 27.02.2013 / 03:50

2 respostas

2

Eu provavelmente escreveria como um loop sobre os nomes gerados por glob:

for f in [abcde].png; do
    convert "$f" -resize 50% "${f%.png}"_half.png
done

Nota: nada no exemplo acima é específico para zsh ; ele deve funcionar em qualquer shell compatível com POSIX ( traço , ksh , bash , zsh , etc .; praticamente qualquer versão moderna de sh ).

Stephane Chazelas também observa que zsh tem um comportamento padrão diferente para quando o glob não corresponde a nenhum arquivo: ele fornece uma mensagem de erro ao invés de usar o próprio padrão como o único "resultado" expansão. Esse comportamento para essa situação também é ajustável em outros shells (por exemplo, as opções failglob e nullglob em bash , o prefixo especial ~(N) glob em ksh , o NOMATCH e NULL_GLOB opções em zsh ).

    
por 27.02.2013 / 04:40
4

As ferramentas do ImageMagick têm um recurso de curinga limitado. Se você passar vários nomes de arquivo ou o caractere curinga literal, ele criará arquivos de saída com numeração sequencial, por exemplo:

convert [a-e].png -resize 50% half.png

cria half-0.png , half-1.png , etc.

Se você quiser corresponder os nomes dos arquivos de entrada, você terá que chamar convert em um arquivo de cada vez, em um loop, explicitamente ou por meio de uma ferramenta. (Alternativamente, você poderia renomear os arquivos depois, mas não há vantagem em fazer isso.) Dentro do loop, você pode usar manipulação de nome de arquivo ou construções de string .

for i in [a-e].png; do
  convert $i -resize 50% %{i:t}_half.png
done

Se você usar isso em um script, convém adicionar o qualificador de glob N para que o padrão de caractere curinga seja expandido para nada se não houver nenhum arquivo correspondente: for i in [a-e].png(N); do …

O Zsh vem com uma ferramenta para renomear arquivos com base em padrões: zmv . Você pode usá-lo para outras transformações baseadas em nome.

autoload -U zmv
zmv -p convert -o '-resize 50%' '([a-e]).png' '${1}_half.png'

Formas alternativas de escrever esses padrões de nome incluem:

zmv -p convert -o '-resize 50%' '([a-e])(.png)' '${1}_half$2'
zmv -p convert -o '-resize 50%' -w '[a-e].png' '${1}_half.png'
zmv -p convert -o '-resize 50%' '[a-e].png' '${f:t}_half.png'

Você pode criar aliases para colocar em seu .zshrc :

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'
alias zconvert='zmv -p convert'

O wrapper a seguir é um pouco melhor do que o alias acima, pois elimina o requisito de passar todas as opções para convert dentro das aspas. Se você passar qualquer zmv opções, elas devem vir antes de todas as opções convert .

zconvert () {
  typeset -a zmv_options=
  while [[ $1 = -[finqQsvwW] ]]; do
    zmv_options+=($1)
  done
  zmv -p convert $zmv_options -o "$@[1,-3]" $@[-2] $@[-1]
}
    
por 28.02.2013 / 12:29

Tags