2
if [[ $1 == *.(png|jpg) ]]

is what I've tried, and it doesn't work. I need to check if $1 matches one of those filename suffixes, so I can then do stuff with it. I'm not sure how to go about this. I'm just getting into bash. I've searched all through these forums, and others. I have yet to find something that works for a conditional if statement.

Kusalananda
  • 333,661

1 Answers1

4

@(this|that) matches this or that in Ksh-style extended globs that Bash also supports. With Bash, you need to use shopt -s extglob to enable extended globs. Since Bash version 4.1, those are enabled by default inside [[ ]] though.

shopt -s extglob # needed in bash-4.0 or older
if [[ $1 == *.@(jpg|png) ]]; then 
    echo match
else
    echo no match
fi

In Zsh, you could use *.(jpg|png) though.

And in standard sh you could use case, but would have to repeat the whole pattern:

case $1 in
    *.png|*.jpg) echo match;;
    *)           echo no match;;
esac

See:

ilkkachu
  • 138,973
  • perfect, thanks. Just one more question though, I've heard that using filename suffixes is unreliable, what would be the better option? Running FILE on each file to determine its type then categorize them from there? Or is this solution fine? – memespace Mar 25 '21 at 16:33
  • @memespace, well, sure it 's not perfect, since if you do mv foo.jpg foo.png, the suffix doesn't match the contents, which might confuse some programs. But it's still by far the most widely used way for telling the file type (I guess you could use extended attributes or such, but they're not portable.) And knowing the file type before trying to interpret it is just useful, in the least it saves time. Also, if you have the same file in different formats, you'd need to figure out some other way to tell the files apart (think prog.c, prog.o and prog; or somedoc.odt, somedoc.pdf etc.) – ilkkachu Mar 25 '21 at 16:38