从 bash 调用 zmv

从 bash 调用 zmv

我最近发现了这种使用以下方法重命名文件的技术zsh

autoload zmv
zmv '(*).JPG' '$1.jpg'

我也可以写成:

autoload zmv; zmv '(*).JPG' '$1.jpg'

这正如所宣传的那样,我可以用它来将大写JPG扩展名更改为小写。

然而,我想从我常用的 BASH shell 中将其作为单行代码运行。当我尝试按如下方式调用它时:

zsh -c "autoload zmv; zmv -f '(*).JPG' '$1.jpg'"

或作为:

echo 'autoload zmv; zmv -f "(*).JPG" "$1.jpg"' | zsh -i

我收到类似以下消息

zmv: error(s) in substitution:
….JPG and ….JPG both map to .jpg

这对我来说意味着zsh处理文件名时不区分大小写,但在第一种方式运行时情况似乎并非如此。

显然,我不知道我在这里做什么。我还尝试反转单引号和双引号,以防 shell 扩展妨碍。

如何从 bash 中将这个命令作为单行命令运行?

答案1

在:

zsh -c "autoload zmv; zmv -f '(*).JPG' '$1.jpg'"

is$1在双引号之间,因此由 shell ( bash) 扩展,最有可能扩展为空字符串,因此zsh最终解释为:

autoload zmv; zmv -f '(*).JPG' '.jpg'

使用:

zsh -c "autoload zmv && zmv '(*).JPG' '\$1.jpg'"

反斜杠在哪里引号for$删除bash双引号内的特殊含义。

您还可以这样做:

zsh -c "autoload zmv && zmv '(*).(#i)jpg' '\$1.jpg'"

在哪里(#i)打开不区分大小写的匹配,因此它也会重命名.Jpg, .JPg, .jpG... 文件。

您还可以将其设为函数:

fix_ext_case() {
  EXT=$1 zsh -c "autoload zmv && zmv \"(*).(#i)\$EXT\" '\$1.\$EXT'"
}

或者使用不同的引号组合:

fix_ext_case() {
  EXT=$1 zsh -c 'autoload zmv && zmv "(*).(#i)$EXT" "\$1.\$EXT"'
}

用作:

fix_ext_case jpg

或者

fix_ext_case png

(或者fix_ext_case JPG如果您想转换为大写)。

相关内容