I am trying to get for each file in a directory, a row with at least, the following fields (the order doesn't matter, although that one is the preferable):

 - Image resolution, in case it is an image. If not, just blank.
 - Modification date
 - Human readable file size
 - Filename

The files in the directory are jpg images and the rest just plain text files. I've tried with something like:

find . -type f -exec paste `identify {} 2> /dev/null` `ls -goh {}` \;

ls tells to me that cannot access {}. The 2> /dev/null part inside identify is for skipping error messages for non-jpg files.

I've also tried with different combinations of xargs and $() and so on, but haven't found a way yet.

Any suggestion?

  • Are you just interested in the current directory's files? Or are you using find because you want the recursive search? – Jeff Schaller Sep 21 '18 at 19:05
  • I'm actually not interested in a recursive search (because there is no subdirs) – Peregring-lk Sep 22 '18 at 0:01

This looks like a good use for an embedded -exec script:

find . -name \*.png -exec sh -c 'printf '%s,%s\\\\n' "$(identify -format '%hx%w' "$1")" "$(stat -c %y,%s,%n "$1")";' bash {} \; > out.csv

Sample output is:

32x32,2018-09-21 15:04:33.216773000 -0400,192,./favicon.png
20x20,2018-09-21 15:04:33.225771000 -0400,1202,./delete.png

Broken up for readability, that script is:

find . -name \*.png -exec sh -c 
  'printf '%s,%s\\\\n' 
     "$(identify -format '%hx%w' "$1")" 
     "$(stat -c %y,%s,%n "$1")";' 
  bash {} \; > out.csv

Note the extra quoting to get a single \n into printf.

Outside of find, to get such output for files in the current directory:

for f in ./*.png
  printf '%s,%s\n' "$(identify -format '%hx%w' "$f")" "$(stat -c %y,%s,%n "$f")"

Sample output is:

20x20,2018-09-21 15:04:33.225771000 -0400,1202,./delete.png
32x32,2018-09-21 15:04:33.216773000 -0400,192,./favicon.png

You can change the pieces out or add other pieces as needed; for 3rd command, just add another %s and quoted command.

I've generated a simplistic CSV-type output, but if your filenames might contain commas, you should quote the filename. Ditto if you convert the file sizes from a simple byte string to one with commas in the thousands places.

  • You could do without printf here since both identify and stat can output à la printf so e.g. sh -c 'identify -format %hx%w, "$1"; stat -c %y,%s,%n "$1"' will do. – don_crissti Sep 21 '18 at 19:39
  • I wanted to do that, @don, but my identify adds a newline to the output – Jeff Schaller Sep 21 '18 at 19:41
  • ImageMagick 6.7.8-9 – Jeff Schaller Sep 21 '18 at 19:46
  • That's really odd... There's an old bug report but they say there it's fixed in 6.2.2 and later... Might as well report this upstream as this clearly should not happen... – don_crissti Sep 21 '18 at 19:49
  • Seem to only add the newline at the end; when given multiple files, it adds it only the one at the end – Jeff Schaller Sep 21 '18 at 19:53

The text in your substitutions is evaluated once before find even start. Note that the preferred way is now $( ). You can pass the commands quoted to a shell, but the easiest way is to just create a script and call the script from find.

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.