Thursday, October 6, 2022

[SOLVED] Glob for file suffix not matching

Issue

I have some Unix command finding mov-files that have a corresponding jpg file:

find . -name '*.[Mm][Oo][Vv]' -exec sh -c '
for mov; do
  for jpg in "${mov%.*}".[Jj][Pp][Gg]; do
    if test -f "$jpg"; then
      echo "$mov" 
    fi
    break
  done
done' sh {} +

The current code just searches for .jpg (or uppercase) as file extension, but I need to extend this to also support files that ends with ".jpeg".

I modified the code to say:

for jpg in "${mov%.*}".[Jj][Pp][Ee]?[Gg]; do

which I believed should make it possible to have an optional "E or e", but this does not work.

I was able to use this instead

for jpg in "${mov%.*}".[Jj][Pp]*[Gg]; do

which is not very safe because it will accept a lot more tha e and E in that position.

Any ideas how to modify expression to add the optional e/E in the reg exp?


Solution

The extglob feature suffices for this. Running shopt -s extglob when using bash (not sh) will let you use ?([Ee]) to refer to zero-or-one instances of [Ee].

Even better, while we're setting shopt flags, we can set nocaseglob so you can use *.jp?(e)g, without the explicit character classes. (The find equivalent for this is changing -name to -iname, which the following does in addition).

find . -iname '*.mov' -exec bash -c '
shopt -s extglob nocaseglob
for mov; do
  for jpg in "${mov%.*}".jp?(e)g; do
    if test -f "$jpg"; then
      printf "%s\n" "$mov" 
    fi
    break
  done
done' bash {} +


Answered By - Charles Duffy
Answer Checked By - Gilberto Lyons (WPSolving Admin)