Shell

從 bash 呼叫 zmv

  • October 27, 2017

我最近發現了這種重命名文件的技術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是不區分大小寫地處理文件名,但在第一種方式執行時似乎並非如此。

顯然,我不知道我在這裡做什麼。我還嘗試反轉單引號和雙引號,以防外殼擴展妨礙。

如何將這個命令作為 bash 的單行命令執行?

在:

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

$1雙引號之間,因此由您的 shell ( bash) 擴展,很可能是空字元串,因此zsh最終解釋為:

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

採用:

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

反斜杠引用$forbash以刪除其在雙引號內的特殊含義。

你也可以這樣做:

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如果你想轉換為大寫)。

引用自:https://unix.stackexchange.com/questions/400799