0

I am using a script for converting all the images in my folder to flop operation. The script is like this:

for f in *.jpg; do
    new="${f%%.jpg}_flop.jpg";
    convert "$f" -flop -quality 100 "$new";
 done

Now I have found that there may be also images with the extension .JPG I thought of adding a new for loop that looks like this:

for f in *.JPG; do
    new="${f%%.jpg}_flop.jpg";
    convert "$f" -flop -quality 100 "$new";
 done

I think that there is a syntax for ignoring the case, and this way I can do a single loop instead of 2, any help?

More, if there will also be the extensions .jpeg or .JPEG, is there a syntax for this, too?

sop
  • 3,445
  • 8
  • 41
  • 84

4 Answers4

1

You can simply do

for f in *.jpg *.JPG; do
    ...

If you want a single expression, you can use the extglob extension in Bash.

set -o extglob
for f in *.@(JP@(|E)G|jp@(|e)g); do
    ...

To make globbing case insensitive, you can shopt -s nocaseglob but there is no particular syntax to make a single glob expression case-insensitive.

You could also use the slightly imprecise

for f in *.[Jj][Pp][Gg] *.[Jj][Pp][Ee][Gg]; do
    ...

to match case-insensitively.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Last option works, but: 1. I have some problems with the extension: If the ext is not the one mentioned after `new="${f%%.here}_flop.jpg";` It is converting to the file file.here_flop.jpg. 2. set -o extglob and shopt does not work for my case, I do not know why (any suggestions?). 3. If I have no files with an ext (like .jpeg) it prints some error, but it does the conversion for the other files – sop Oct 06 '14 at 11:37
  • I can speculate that you are using `#!/bin/sh` on the shebang line, which runs a different shell, or (on some installations) Bash with all Bash-specific extensions disabled. – tripleee Oct 06 '14 at 12:27
0

Something along these lines:

#/bin/bash
shopt -s nullglob                # don't give error messages if no matching files
shopt -s nocaseglob              # ignore case
for f in *.jpg *.jpeg; do

   new=${f/.[Jj][Pp][Ee][Gg]/}      # strip extension
   new=${new/.[Jj][Pp][Gg]/}        # whether JPEG or jpg
   new="$new_flop.jpg"

   convert "$f" -flop -quality 100 "$new"
done
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • `flop_all_images.sh: 1: flop_all_images.sh: shopt: not found flop_all_images.sh: 2: flop_all_images.sh: shopt: not found flop_all_images.sh: 4: flop_all_images.sh: Bad substitution` How to enable shopt ? – sop Oct 06 '14 at 09:23
  • Sorry, it is a bash-ism. You need `#!/bin/bash` as the first line. – Mark Setchell Oct 06 '14 at 09:24
  • I've added it, but still saying the `shopt: not found`. And still `Bad substitution`. – sop Oct 06 '14 at 09:29
  • Try making the first line `#!/bin/bash -xv` and running it again to debug – Mark Setchell Oct 06 '14 at 09:31
  • Try `which bash` and `bash -version` – Mark Setchell Oct 06 '14 at 09:46
  • GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu) – sop Oct 06 '14 at 09:47
  • I am running the code you have posted (copy paste) and I am getting the 3 lines of errors: `shopt: not found` and `Bad substitution` (the ones that I have posted in the first comment) – sop Oct 06 '14 at 11:16
  • Bad substitution is here: `new=${f/.[Jj][Pp][Ee][Gg]/}` – sop Oct 06 '14 at 11:29
  • I have no idea what is going on! Maybe you can paste following into your shell and experiment till you find the syntax your `bash` understands.... `f=abc.jpEg; new=${f/[Jj][Pp][Ee][Gg]/fred}; echo $new` It should say `abc.fred` whatever you do with the `JPEG|jpg` part. – Mark Setchell Oct 06 '14 at 11:37
  • Interesting: if I post it in the script, then I get the bad substitution error, and if I just type it in terminal, it does what you expect. – sop Oct 06 '14 at 11:45
  • I am assuming you saved my script in a file as, say `go`, then did `chmod +x go` followed by `./go` – Mark Setchell Oct 06 '14 at 12:21
  • yes, `flop_all_images.sh`, then `chmod +x flop_all_images.sh` then `./flop_all_images.sh`. How would you suggest me to do instead of this? – sop Oct 06 '14 at 12:51
  • That is the correct approach already, I was worried you were just pasting the whole script into the shell, but it is ok, you are not. I can only speculate, like @tripleee that you are somehow not using normal `bash`. – Mark Setchell Oct 06 '14 at 13:01
  • Maybe one of my heroes, @anubhava will have a moment and be able to take a look and suggest something... – Mark Setchell Oct 06 '14 at 13:02
  • by the way, which bash is printing `/bin/bash` – sop Oct 06 '14 at 13:06
  • Try `ls -l /bin/bash` to see if it symlinked to `sh` or something. – Mark Setchell Oct 06 '14 at 15:19
  • `-rwxr-xr-x 1 root root 1021112 sept. 27 10:04 /bin/bash` what does this means? :) – sop Oct 07 '14 at 07:21
  • 1
    It means your `bash` is not symbolically linked to some other shell such as `fish` or `sh`, so that is not the cause of the problems either. – Mark Setchell Oct 07 '14 at 07:57
0

I have a script that does something similar:

for file in {*.jpg,*.JPG}; do
  mv "$file" "old$file"
  convert -resize 3000000@\> "old$file" -quality 80 "$file"
  rm "old$file"
done

I also made a video explaining it: https://www.youtube.com/watch?v=AG0bItQLBdI

Sebastian Bartos
  • 2,317
  • 1
  • 20
  • 20
  • `{*.jpg,*.JPG}` makes the echo to print `convert *.jpg, to *.jpg,_flop.jpg` (etc) – sop Oct 06 '14 at 11:40
  • it's a script, see other comments. The command looked like `for file in {*.jpg,*.JPG}; do new="${f%%.jpg}_flop.jpg"; convert "$f" -flop -quality 100 "$new"; done`, but i have changed it to `for f in *.[Jj][Pp][Gg] *.[Jj][Pp][Ee][Gg]; do new="${f%%.[Jj][Pp][Gg]}_flop.jpg"; convert "$f" -flop -quality 100 "$new"; done` and I just get just the errors of no such an extension kind. – sop Oct 07 '14 at 07:30
-1
for f in `ls * | grep -i "jp[e]\?g$"`;do
   new="${f%%.jpg}_flop.jpg";     
   echo convert "$f" -flop -quality 100 "$new";  
done

Regular expressions are your friend.

Matthew V Carey
  • 196
  • 1
  • 10