I'm trying to write a script (or a one-liner) that finds all image files with small dimensions and then moves them into a directory. Based on this answer from Ask Ubuntu, I was able to generate a list of files with both dimensions lower than 500, and then I was able to find all common images files as well as .jpg.

find -E . -regex ".*\.(jpg|gif|png|jpeg)" -type f -exec identify -format '%w %h %i\n' '{}' \; | awk '$1<500 && $2<500' | awk '{print $3}'

The second awk is so that it only prints the file name, which I was hoping to use in the input to mv. How can I get that output into mv?

Sample output of the first awk is:

123 456 ./smallimage.jpg
333 333 ./square.png

The second awk just gives out


However, I can't seem to find a way to get this list of filenames as the input for an mv command, as the desired resulting final command is some form of mv <file list> ./small_images/


Incorporate mv into awk using the system() function:

awk '$1<500 && $2<500 {system("mv "$3" /destination")}

Change the mv command to meet your need, here i have used:

mv /file_(third_field)_from_awk /destination

Also you don't need multiple awks, only one would suffice as shown above.

| improve this answer | |
  • That's good, but please consider that some filenames could contain spaces, which can break the system() call. – Sergiy Kolodyazhnyy Jan 10 '17 at 6:09
  • That worked! Thanks for the fast answer; turning $3 into substr($3,3) (and testing by turning system to print) gave almost exactly the result I wanted. The only other thing I'd want to do is make the regex ignore subdirectories and case-insensitive to the file extension. – cjm Jan 10 '17 at 6:11
  • My final one-liner ended up as find -E . -iregex ".*\.(jpg|gif|png|jpeg|bmp)" -type f -exec identify -format '%w %h %i\n' '{}' \; | awk '$1<500 && $2<500 {system("mv "substr($3,3)" small_images/"substr($3,3)"")}'. You could add more image formats if you really wanted to, but I'm pretty sure I don't have any tga or tiff files that I'm interested in. – cjm Jan 15 '17 at 2:44

With the assumption that you are not having filenames with embedded newlines, you can use the GNU mv and xargs programs to do this.

 ... | awk ... | xargs -d'\n' mv -t ./small_images

xargs collects the filenames from the input and appends them onto the mv -t ./small_images command, splitting very long commands as needed. You need a version of mv that has the -t option to specify the destination directory at the start of the command, or else write a tiny script to handle it.

| improve this answer | |
  • How would that handle files in subdirectories or those already moved? – cjm Jan 10 '17 at 12:24

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.