[GTALUG] Help need in bash

D. Hugh Redelmeier hugh at mimosa.com
Fri Jun 1 13:55:45 EDT 2018


| From: Stewart C. Russell via talk <talk at gtalug.org>

| On 2018-05-31 03:00 PM, Stewart Russell wrote:
| > 
| >   convert file.{png,jpg}
| > 
| > and bash will do the magic. What I don't know is if that will accept a
| > glob. 
| 
| narrator voice: it didn't accept a glob.
| 
| (that is,
| 
| 	convert *.{png,jpg}
| 
| does *something*, but neither what you'd expect nor want)

Image Magick's convert command sure is magic.  But its syntax does not
follow UNIX conventions.

SYNOPSIS
       convert [input-option] input-file [output-option] output-file

"accept a glob" is not a UNIX thing.  globbing is done by the shell.  
What you mean is: accepts a sequence of pathnames on the command line, 
often denoted "file..." in a synopsis.  Like this

SYNOPSIS
       cat [OPTION]... [FILE]...

The convert synopsis is actually wrong, I think.  I think that it
should be

       convert [input-option]... input-file [output-option]... output-file

What you wanted to do is actually more awkward in UNIX than in systems
where the globbing is done by the program (I think).  In those
systems, the "filename extension" is a first-class notion.

for i in *.png ; do convert "$i" "$(basename "$i" .png).jpg" ; done

I don't even understand why the inner quotes don't need to be escaped.
I tested it with this simulation:
    for i in "hello.png" "good bye.png" ; do echo convert "$i" "$(basename "$i" .png).jpg" ; done

basename strips any directory prefix off of its argument but I didn't
worry because *.png won't produce paths with directory prefixes.
Beware if you try to generalize this code.

bash has powerful but odd macro substitution operators.  Here's a
version of the code where the basename has been replaced by one of
these operator.  I have no idea if this works in other shells

for i in *.png ; do convert "$i" "${i%.png}.jpg" ; done

(I learned the Bourne shell in the 1970's and usually stick to that
original simple language.  I have to read bash(1) to find things like 
this.)


More information about the talk mailing list