G'MIC conundrum

A while ago I made a shell script for output-sharpening a number of jpg files in a folder exported from DT. To sidestep the issue where G’mic throws an error with spaces in path names, the file names are put in double quotes:

for i in *.jpg; do  
    gmic "$i" -deblur_richardsonlucy 0.70,30,1 cut 0,255 round o "$i",95 
done

The script works correctly through a folder with jpg files, however, a file name with a space in it produces the dreaded error that a jpg,95 format cannot be recognized. Where did I go wrong here?

the general solution to whitespaces in filenames is use the null byte

find -name \*.jpg -print0  |\
  xargs -I '{}' -r0 \
  gmic "{}" -deblur_richardsonlucy 0.70,30,1 cut 0,255 round o "{}",95

untested. but according to the man page that should work.

if you only want the files in the current directory and not go into sub directories

find -maxdepth 1 -name \*.jpg -print0  |\
  xargs -I '{}' -r0 \
  gmic "{}" -deblur_richardsonlucy 0.70,30,1 cut 0,255 round o "{}",95

or you know … stop using shell scripts all together:

#!/usr/bin/ruby

Dir["\*.jpg"].each do |filename|
  cmdline = ["gmic", filename, "-deblur_richardsonlucy", "0.70,30,1", "cut", "0,255", "round", "o", "#{filename},95"]
  system(*cmdline)
end
2 Likes

G’MIC can loop as well.

gmic ig *.jpg foreach nm={b} deblur_richardsonlucy 0.70,30,1 c 0,255 round nm $nm o {b}_processed.jpg,95 done

ig → shortcut for input_glob
foreach...done → iterates images in buffer
nm={b} → stores filename without extension
nm $nm → restores image name (RL filter unfortunately appends _c1, so this is a workaround to avoid it from happening when outputting)

To prevent substitution issues, do the same thing darix suggested, except place the command portion in a *.gmic file. I.e.,

gmic RL_deblur.gmic

ig *.jpg
foreach nm={b}
  deblur_richardsonlucy 0.70,30,1
  c 0,255 round
  nm $nm
  o {b}_processed.jpg,95
done
2 Likes

The double quotes must be passed to G’MIC too, and your shell probably does not do it (it interprets the double quotes for itself). It’s important then to backslash the double quotes.
Try this:

for i in *.jpg; do  
    gmic \"$i\" -deblur_richardsonlucy 0.70,30,1 cut 0,255 round o \"$i\",95 
done
1 Like

the for loop would already break file names. so if you had “foo bar.jpg”
then the gmic cmline would be called with “foo” and “bar.jpg”

1 Like

Thanks for the input everyone!
Escaping the double quotes looks fairly straightforward. But it took me quite a bit of reading to at least superficially understand what these rest of these commands are doing (always boggles my mind to see command line fu in the hands of an expert).
I’ll give that a try when I get home tonight.

While spaces in shell are a horror, at least for bash this exact detail is not true. Of course, if you do for i in "*.jpg"; do echo $i; done instead of for i in *.jpg; do echo $i; done then the behavior you described would occur. And there is nullglob to consider. I second your recommendation of not using shell when this kind of shenanigans must be avoided.