2

I have already found an answer that lists pretty much everything. Except I cannot get it to work.

I use:

find . -iname "*.jpg" -type f | xargs -I{} identify -format '%w %h %i' {} | awk '$1<300 || $2<300{print $3}'

What is needed to remove the output files?
I tried adding | rm at the end but an error shows that im missing an opperand. I want all the files that the code above prints to be deleted.

Can someone please help

2
  • I think you can use rm $(find...$3}'). In other words, wrap the above command inside the parens in $() to use the results as an argument to rm.
    – chaskes
    Feb 4, 2015 at 23:52
  • Cool. Thanks for letting me know. I'll move it to an answer.
    – chaskes
    Feb 18, 2015 at 20:05

4 Answers 4

1

The following works and is very fast. Save to ~/checksize.sh and make it executable with chmod (chmod +x ~/checksize.sh)

#! /bin/bash

#find . -type f -exec bash -c ~/checksize.sh ;
echo ${@}
if [ -z "$1" ]
then
    echo "\$1 empty" >&2
    exit
fi

size=($(identify -format "%w %h" "$1" | tr -d "()"))
#echo ${size[@]}
#echo ${size[0]}
#echo ${size[1]}
if [ ${size[0]} -lt 300 -a ${size[1]} -lt 300 ]
then
    rm -v "$1"
fi

Then change directory into the directory you want to remove the files that are too small from.

After cd'ing into the directory, run the following: find . -type f | xargs -P 0 -L 1 ~/checksize.sh

It runs fast because it uses xarg's -P 0 which makes xarg run with the maximum amount of paralellity possible. See its man page for details.

1

rm doesn't read filenames from input. You can probably do:

find . -iname "*.jpg" -type f -exec bash -c 'for i; do size=($(identify -format "%w %h" "$i")); (( size[1] < 300 || size[2] < 300 )) && rm -v "$i"' remove-files {} +
  • You can use -exec instead of xargs.

The bash command:

for i
do
    size=($(identify -format "%w %h" "$i"))
    (( size[0] < 300 || size[1] < 300 )) && rm -v "$i"
done
  • loops over all the input arguments (for i)
  • gets the size and stores it in an array (that's why there are parentheses around $(): ($(identify -format "%w %h" "$i"))
  • uses shell arithmetic (( )) to do the comparison
5
  • What is remove-files doing at the end of the command here? Dec 31, 2019 at 1:36
  • 1
    Should't it be (( size[0] < 300 || size[1] < 300 ))? Jan 2, 2020 at 0:01
  • @KamilMaciorowski yep, I was using zsh when wrote this, and carried over those indexes.
    – muru
    Mar 19, 2020 at 2:40
  • 1
    @Hashim it's $0 for bash, which in this case will be used for reporting errors from bash (so if there's an error, bash would print remove-files: ...
    – muru
    Mar 19, 2020 at 2:41
  • 1
    @Hashim More about remove-files: here. In this case the argument is important not only for reporting errors. If {} directly followed the code, then for i wouldn't process all the files. Mar 19, 2020 at 5:11
0

You should be able to use rm $(find...$3}').

In other words, wrap the above command inside the parentheses in $() to use the results as an argument to rm.

0

For those who need this way for current Bash, here is the modernized form for saving arrays.

#!/bin/bash

for i in ./*.png; do
    mapfile -d " " -t size < <( identify -format "%w %h" "$i" )
    if [ "${size[0]}" -lt 1920 ] && [ "${size[1]}" -lt 1080 ]; then
        rm -v "$i"
    fi
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .