Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I need to create both TIF and JPG versions of a large set of images.

All JPG images already exist, but only a part of the TIF images. Is there an easy way to search a directory to find all JPG files that have no corresponding TIF file (i.e. a file with the same name but with different file extension)?

share|improve this question
    
Wish I saw this earlier, asked a similar question today. –  Rob Oct 27 '11 at 17:47

6 Answers 6

up vote 3 down vote accepted

Perl one-liner:

find . -name '*.jpg'|perl -nle 's/\.jpg//;unless(-f "$_.tif"){print "$_.jpg"}' 

In 63 characters:

find . -name '*.jpg'|perl -pnle 's/.jpg//;-f "$_.tif"||"$_.jpg"' 
share|improve this answer
    
Interesting... But when I tried it I got the following error (pls note that I don't know perl at all...): Anderss-MacBook-Pro:Temp Anders$ perl hello.pl String found where operator expected at hello.pl line 2, near "name '.jpg'" (Do you need to predeclare name?) String found where operator expected at hello.pl line 2, near "pnle 's/.jpg//;-f "$_.tif"||"$_.jpg"'" (Do you need to predeclare pnle?) syntax error at hello.pl line 2, near "name '.jpg'" Execution of hello.pl aborted due to compilation errors. –  Anders Svensson Oct 10 '11 at 21:28
    
I'm guessing you just left out something that you assumed I would know :-). BTW, is there any way of making this recursive to check subdirectories as well, with directory names printed out? –  Anders Svensson Oct 10 '11 at 21:30
    
Woops, you run this from the command line, not from inside a perl script. Just cut and paste into terminal when you're in the directory w/ the images. This should cover subdirectories, but the files list as "directory/file1", "directory/file2", etc. –  barrycarter Oct 10 '11 at 22:25
    
Ok, that's pretty nice! Actually, only the first one worked though, not the second one. That one only listed all the files... Shouldn't you be able to run this in a file though? I read a reeally short intro to perl, where you put the script in a .pl file and ran it from Terminal. That would be good to have in case I need to reuse it, instead of having to paste in this each time... Thanks –  Anders Svensson Oct 10 '11 at 23:03
    
Yes, I realized later that the second one was broken. This is really a combination of Unix commands and perl. If you want, you can put it a file called "something.sh" and then do "sh something.sh" (or "bash something.sh"). If you have 'convert' (ImageMagick), you can even convert the jpgs to tiffs. –  barrycarter Oct 11 '11 at 1:12

Assuming all images are in the images directory and has the .jpg suffix, the following little script will print out all image files that has no corresponding .tif file on UNIX:

#!/bin/sh

find images/ -type f -name "*.jpg" |
while read j; do
  t=${j%.jpg}.tif
  if [ ! -f "$t" ]; then
    echo "Lacking tif file: " $j
  fi
done

Paste this to a file, and save it a folder above the one where your images are stored. You could call it find-images. For example:

├── find-images
└── images/
    ├── 1.jpg
    └── 2.jpg
    └── ...

Now, open Utilities/Terminal.app, and use the cd command to navigate to the folder where your script is, e.g. if the script is on your Desktop, just enter cd Desktop.

Then, enter chmod +x find-images. Now you can run the script by just calling ./find-images.

share|improve this answer
    
Ok, this sounds sort of doable. I'm on a Mac, which is a kind of Unix, but I'm really new to the Mac. Do I put this script in Terminal or do I somehow create a script file (bash I suppose...)? –  Anders Svensson Oct 10 '11 at 16:43
    
@AndersSvensson I added some information about how to run it. KAK, hope you don't mind. –  slhck Oct 10 '11 at 18:00
    
This works nicely, and simple enough, thanks. Just a follow-up question: is there any simple way to make it recursive, and check all subdirectories as well? Preferably printing out the name of the directory, like in sections of the result file? –  Anders Svensson Oct 10 '11 at 20:34
    
Sorry, just noticed it did actually check recursively... Just ran it on a test folder first which didn't have subdirs... I still have to choose the perl solution, because that worked with all files, this one failed on files with spaces in the names. Thanks though. –  Anders Svensson Oct 10 '11 at 23:03
    
@slhck, no worries. –  Kusalananda Oct 11 '11 at 8:23

I'll use Python, since it is cross-platform. First put your jpg and tif files in separate folders.

import os

jpgPath = "path/to/jpgs/folder"
tifPath = "path/to/tifs/folder"

jpgList = [item.rsplit(".", 1)[0] for item in os.listdir(jpgPath)]
tifList = [item.rsplit(".", 1)[0] for item in os.listdir(tifPath)]

diffList = [item for item in jpgList if item not in tifList]

print diffList

Then, save this script to a file, somewhere on your hard drive, maybe under the name find-images.

Now, open Utilities/Terminal.app, and enter python /path/to/file. For example, if you saved it on your Desktop, it would be python ~/Desktop/find-images (since ~ is a shortcut to your home folder). Here, you can run a more detailed explanation on running Python files on your Mac.

share|improve this answer
3  
You need to strip file extensions first, otherwise none of the files will match. I would guess [item.rsplit(".", 1)[0] for item in os.listdir(jpgPath)]... –  grawity Oct 10 '11 at 16:04
    
Hmm, ok thanks, but I have no idea how to use Python. I'm on a Mac, would Python work in Terminal, or what do I do? @grawity: and where would I place this stripping of the extensions command? –  Anders Svensson Oct 10 '11 at 16:41
    
@grawity Oh right. Silly me. Edited. @AndersSvensson Python should be pre-installed on your mac. Just type python into Terminal and paste in the above code. –  Samuel Oct 10 '11 at 17:26

Ah, I felt like adding this. Here's the solution in Ruby, which prints every image that has no TIF counterpart:

jpg = Dir["*.jpg"]
tif = Dir["*.tif"]    
[jpg, tif].each { |a| a.map!{ |f| f[0..-5]} }
puts jpg - tif

Put it into a file which resides in the same folder as your images, save it as find-images, and run it in Terminal by entering ruby find-images.

If you don't know Ruby, don't ask how it works, might take a while to explain :P

share|improve this answer
1  
A more generic version: a0, a1 = ARGV[0], ARGV[1]; dir0 = Dir["*.#{a0}"]; dir1 = Dir["*.#{a1}"]; dir0.each {|f| puts f unless dir1.include?(f.sub(/\.#{a0}$/, ".#{a1}"))} –  Lri Oct 11 '11 at 9:34
    
@Lri Hah. Pretty neat. Still learning – the parallel assignment is something I have to use more often. –  slhck Oct 11 '11 at 9:38

diffext

#!/bin/bash

found1=$(find "$PWD" -name "*.$1")
found2=$(find "$PWD" -name "*.$2")
export IFS=$'\n'
for f1 in "$found1"; do
    base1=${f1##/}
    for f2 in "$found2"; do
        base2=${f2##/}
        [[ ${base1%.$1} == ${base2%.$2} ]] && continue 2
    done
    echo "$f1"
done
  • Usage: cd somedir; diffext jpg tif
  • Searches recursively in subdirectories of the current directory
    • Treats files as duplicates even if they were in different directories
share|improve this answer

One-liner(s) without perl:

With using while loop after find:

find . -name '*.jpg' | while read file ; do test ! -f `dirname $file`/`basename $file .jpg`.tif && echo $file; done

With using (lots of) subshells:

find . -name '*.jpg' -exec sh -c 'test ! -f `echo {} |sed s/\.jpg$/.flac/` && echo {}' \;
share|improve this answer
    
This would work with file names that have spaces and print the absolute paths: diffexts() { find "$PWD" -name "*.$1" | while read f; do [[ ! -e ${f%.$1}.$2 ]] && echo "$f"; done; } –  Lri Oct 28 '11 at 6:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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