1

I have recently discovered this technique for renaming files using zsh:

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

which I can also write as:

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

This works as advertised and I can use it to change the Upper Case JPG extension to lower case.

However, I would like to run this as a one-liner from my usual BASH shell. When I try to call it as follows:

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

or as:

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

I get something like the following message

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

This suggests to me that that zsh is treating the file names case-insensitively, but that does not appear to be the case when run the first way.

Obviously, I don’t know what I’m doing here. I have also tried reversing the single and double quotes in case shell expansion is getting in the way.

How can I run this command as a one-liner from bash?

1 Answer 1

6

In:

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

The $1 is between double quotes, so expanded by your shell (bash), most probably to the empty string so zsh ends up interpreting:

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

Use:

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

Where the backslash quotes the $ for bash to remove its special meaning inside double quotes.

You can also do:

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

Where (#i) is to turn on case-insensitive matching so it also renames the .Jpg, .JPg, .jpG... files.

You could also make it a function:

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

Or with a different combination of quotes:

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

To be used as:

fix_ext_case jpg 

or

fix_ext_case png 

(or fix_ext_case JPG if you want to convert to upper-case).

1
  • Excellent. The `` did the trick. Thanks also for your additional information. Commented Oct 27, 2017 at 11:55

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.