如何在 zsh 中获取“当前 glob”

如何在 zsh 中获取“当前 glob”

我想做类似的事情:

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

我怎样才能做到这一点?是否有一些变量存储当前匹配?我在文档中找不到任何内容,但也许我正在寻找错误的关键字。

我想也许我可以做到这一点xargs,但我也无法解决。

答案1

ImageMagick 工具的通配符功能有限。如果传递多个文件名或文字通配符,它​​将创建具有顺序编号的输出文件,例如:

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

创建half-0.pnghalf-1.png

如果要匹配输入文件名,则必须convert在循环中显式或通过工具一次调用一个文件。 (或者,您可以稍后重命名文件,但这样做没有任何优势。)在循环内,您可以使用 zsh文件名操作或者字符串操作结构体。

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

如果您在脚本中使用它,您可能需要添加N 全局限定符这样,如果没有匹配的文件,通配符模式将扩展为空:for i in [a-e].png(N); do …

Zsh 附带了一个根据模式重命名文件的工具:zmv。您可以将其用于其他基于名称的转换。

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

编写这些名称模式的替代方法包括:

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'

您可以创建别名并放入您的.zshrc

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

下面的包装器比上面的别名好一点,因为它消除了将所有选项传递到convert内部引号的要求。如果您通过任何zmv选项,它们必须位于所有convert选项之前。

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

答案2

我可能会将其写为对 glob 生成的名称的循环:

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

注意:上面的例子中没有任何特定内容;它应该在任何 POSIX 兼容的 shell 中工作(短跑,克什,巴什,, ETC。;包括几乎任何现代版本)。

斯蒂芬·查泽拉斯还指出当 glob 无法匹配任何文件时,有不同的默认行为:它给出错误消息,而不是使用模式本身作为扩展的唯一“结果”。这种情况下的这种行为也可以在其他 shell中进行调整(例如failglobnullglob巴什,特殊的~(N)全局前缀克什NOMATCHNULL_GLOB中的选项)。

相关内容