30

I know that is possible to use for loop with find command like that

for i in `find $something`; do (...) done

but I want to use find command with "if".

I am trying to create progress comments (and log files later) about removed files by my script. I need to check if

find /directory/whatever -name '*.tar.gz' -mtime +$DAYS

found something or not. If not I want to say echo 'You don't have files older than $DAYS days' or something like this ;)

How I can do that in shell script?

oguz ismail
  • 1
  • 16
  • 47
  • 69
Izzy
  • 755
  • 2
  • 9
  • 17

6 Answers6

29

Count the number of lines output and store it in a variable, then test it:

lines=$(find ... | wc -l)
if [ $lines -eq 0 ]; then
...
fi
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
18

To use the find command inside an if condition, you can try this one liner :

 [[ ! -z `find 'YOUR_DIR/' -name 'something'` ]] && echo "found" || echo "not found"

Example of use :

 [prompt] $ mkdir -p Dir/dir1 Dir/dir2/ Dir/dir3                 
 [prompt] $ ls Dir/
 dir1  dir2  dir3
 [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found"
 not found
 [prompt] $ touch Dir/dir3/something
 [prompt] $ [[ ! -z `find 'Dir/' -name 'something'` ]] && echo "found" || echo "not found"
 found

Alternatively, -n can be used instead of ! -z, for example:

[[ -n `find $dir -name $filename` ]] && echo found

From man test:

-n STRING
       the length of STRING is nonzero
Nagev
  • 10,835
  • 4
  • 58
  • 69
bachN
  • 592
  • 3
  • 14
11

Exit 0 is easy with find, exit >0 is harder because that usually only happens with an error. However we can make it happen:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi
Zombo
  • 1
  • 62
  • 391
  • 407
  • 1
    This is not correct. The question asks how to return false if it DOES NOT find anything. -exec will only run if it does find something so this would never work properly. – deltaray Apr 21 '20 at 15:40
  • 1
    @deltaray: This answer returns false when files are found and true when they're not. Simply negate the result with a `!` or use the then/else as shown which is set up in a negated form. – Dennis Williamson Mar 16 '21 at 16:33
4

I wanted to do this in a single line if possible, but couldn't see a way to get find to change its exit code without causing an error.

However, with your specific requirement, the following should work:

find /directory/whatever -name '*.tar.gz' -mtime +$DAYS | grep 'tar.gz' || echo "You don't have files older than $DAYS days"

This works by passing the output of find into a grep for the same thing, returns a failure exit code if it doesn't find anything, or will success and echo the found lines if it does.

Everything after || will only execute if the preceding command fails.

Andrew Stubbs
  • 4,322
  • 3
  • 29
  • 48
4

This worked for me

if test $(find . -name "pattern" | wc -c) -eq 0
then
    echo "missing file with name pattern"
fi
Rishabh Agarwal
  • 2,374
  • 1
  • 21
  • 27
2

Iterating over the output of find might be dangerous if your filenames contain spaces. If you're sure they don't, you can store the result of find to an array, and check its size to see there were any hits:

results=( $(find -name "$something") )
if (( ${#results[@]} )) ; then
    echo Found
else
    echo Not found
fi
for file in "${results[@]}" ; do
   # ...
done
choroba
  • 231,213
  • 25
  • 204
  • 289