6

I have work with find before to find all specific files in a folder and subfolder and do something about it

For example, I did use

find /folder/ -name '*.txt' -exec chmod 666 {} \;

This code to easy change write access to every text file in the folder.

Now I was going to try to convert every jpg(even JPG) to gif in the same way but not sure if that is so easy. When I try with the convert command tools it wants to have an inputfilename and output filename but I do not think find give that so maybe find is not the right Tools to use?

5
  • 1
    Do you mean X amounts of jpegs so you get 1 GIF. Or 1 gif for every jpeg? – Rinzwind Jul 27 '19 at 13:32
  • 1
    Note that your example makes the *.txt files world-writable with that mode 666. That is almost never a good idea. – marcelm Jul 28 '19 at 9:10
  • 1
    Why do you want GIF in this day and age except for animation? – chrylis -cautiouslyoptimistic- Jul 28 '19 at 12:28
  • Note that GIF supports upto 256 colours from a 24-bit palette. JPG supports 24-bit colours. You are likely to introduce dithering artefacts doing this – CSM Jul 28 '19 at 16:52
  • Well that is true that is not good idea to make every textfile 666 but when I did use this code I did have to do that to make some script work. Some file is GIF as default and some was JPG, that I have done now is just use at it is. – Cazz Jul 28 '19 at 18:29
8

Find can be used for this, but I find it easier to use the shell instead. If your files are all in the same directory (no subdirectories) you can just do:

for f in /path/to/dir/*jpg /path/to/dir/*JPG; do
    convert "$f" "${f%.*}.gif"
done

The ${var%something} syntax will remove the shortest match for the glob something from the end of the variable $var. For example:

$ var="foo.bar.baz"
$ echo "$var : ${var%.*}"
foo.bar.baz : foo.bar

So here, it is removing the final extension from the filename. Therefore, "${f%.*}.gif" is the original file name but with .gif instead of .jpg or .JPG.

If you do need to recurse into subdirectories, you can use bash's globstar option (from man bash):

globstar
    If set, the pattern ** used in a pathname expansion con‐
    text will match all files and zero or  more  directories
    and  subdirectories.  If the pattern is followed by a /,
    only directories and subdirectories match.

You can enable it with shopt -s globstar:

shopt -s globstar
for f in /path/to/dir/**/*jpg /path/to/dir/**/*JPG; do
    convert "$f" "${f%.*}.gif"
done
1
  • Ahh globstar was something new for me, and it works greate that you give me. – Cazz Jul 27 '19 at 17:56
5

You can indeed use find - with a shell wrapper that calls the appropriate convert command and generates the output file using paramemter substitution. Ex.

find . -name '*.jpg' -execdir sh -c '
  for f; do convert -verbose "$f" "${f%.*}.gif"; done
' find-sh {} +

Change -name to -iname to include the .JPG extension (although note that the replacement .gif extension will be lower case regardless).

2
  • wow nice, nice to know if I need to change something easy and fast – Cazz Jul 27 '19 at 17:56
  • Why ask find to combine a whole bunch of results into a single commandline, only to split them apart again? – Ben Voigt Jul 28 '19 at 5:25
1

There's another tool in ImageMagick, mogrify, that's designed to make batch processing easy. This does what you want:

shopt -s globstar
mogrify -format gif **/*.jpg
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.