Shell script to separate and move landscape and portrait images
You could use imagemagick
's identify
with the fx
special operator to compare height and width e.g. h>w
. If true it will output 1
, if false it will output 0
:
for f in ./*.jpg
do
r=$(identify -format '%[fx:(h>w)]' "$f")
if [[ r -eq 1 ]]
then
mv "$f" /path/to/portraits
else
mv "$f" /path/to/landscapes
fi
done
With zsh
you could use the e
string glob qualifier (to select only the files for which the code between quotes returns true
) and do something like:
mv ./*.jpg(.e_'identify -format "%[fx:(h>w)]" $REPLY | grep 0 >/dev/null'_) /path/to/landscapes
mv ./*.jpg /path/to/portraits
so the first command moves all landscape images to /path/to/landscapes
and the second one moves the remaining images to /path/to/portraits
.
The above solutions will treat square images as landscapes and move them into the respective directory. You could introduce a second condition if you wanted to move them to their own directory:
mv ./*.jpg(.e_'identify -format "%[fx:(h<w)]" $REPLY | grep 1 >/dev/null'_) /path/to/landscapes
mv ./*.jpg(.e_'identify -format "%[fx:(h>w)]" $REPLY | grep 1 >/dev/null'_) /path/to/portraits
mv ./*.jpg /path/to/squares
or you could use a different condition (e.g. check h/w
ratio) to separate the square images from the rest and leave them in the current directory:
for f in ./*.jpg
do
r=$(identify -format '%[fx:(h/w)]' "$f")
if [[ r -gt 1 ]]
then
mv "$f" /path/to/portraits
elif [[ r -lt 1 ]]
then
mv "$f" /path/to/landscapes
fi
done
This uses the fileinfo
utility to get an image's width and height. If the height is greater than the width, the file is moved to the portraits/
directory. If not, it is moved to the landscape/
directory.
for f in ./*jpg
do
if fileinfo "$f" 2>&1 | awk '/w =/{w=$3+0; h=$6+0; if (h>w) exit; else exit 1}'
then
mv "$f" portraits/
else
mv "$f" landscape/
fi
done
The file name in this loop is double-quoted where needed so that this loop is safe to use even for image file names with spaces, newlines, or other difficult characters.
On a debian-like system, fileinfo
can be installed via:
apt-get install leptonica-progs
Other similar utilities can be used as long as the awk command is modified appropriately.
Using identify
from ImageMagick:
#! /bin/sh
identify -format '%w %h %i\n' -- "$@" 2>/dev/null | \
while read W H FN; do
if [ $W -gt $H ]; then
echo mv -f -- "$FN" /path/to/landscape/
else
echo mv -f -- "$FN" /path/to/portraits/
fi
done
This is not particularly efficient because it runs mv
for each file, but you didn't ask for efficiency.