LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 05-18-2011, 09:33 AM   #1
catalint
LQ Newbie
 
Registered: May 2011
Posts: 7

Rep: Reputation: 0
find command return true if a file was found


Hello there,

Anyone knows how to manage the find command to return true or false if a file was found/or not? I tried to man find but didn't found anything.

Regards,
 
Old 05-18-2011, 09:39 AM   #2
Chirel
Member
 
Registered: Nov 2009
Posts: 55

Rep: Reputation: 19
Hi,

the find command will only return non zero value on error, so it will return 0 if it find or not file.
A solution could be to pipe the output to grep -q who will return non zero if not found.
Something like that :
Code:
find . -name 'filename' | grep -q filename && echo "File found" || echo "File not found"
I'm sure there are more optimized solution, but it's the first that came to me.

Solution 2:
Code:
[ -n "$(find . -name 'filename' 2>/dev/null)" ] && echo "File found" || echo "File not found"

Last edited by Chirel; 05-18-2011 at 09:42 AM.
 
Old 05-18-2011, 09:39 AM   #3
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 555

Rep: Reputation: 75
The return value of find ./ -name does_not_exist = 0; Also find ./ -name does_exist returns 0.

So, what can you do?

Code:
if [ $(find ./ -name does_exist | wc -l) -gt 0 ]
then
   echo "Found something"
else
   echo "Found nothing
fi
wc -l will count the lines, which will be >0 if something was found, and 0 if nothing was found.

Edit: The solution looks different, but is essentially the same; Chirel beat me to it ;-)

Last edited by Ramurd; 05-18-2011 at 09:41 AM.
 
Old 05-18-2011, 11:29 AM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
I recommend using a short-circuited version of Chirel's solution:
Code:
FILE=`find . -name 'filename' -print -quit`

if [ -n "$FILE" ]; then
    echo "Found $FILE"
else
    echo "Not found."
fi
The -quit option tells find to not do any further searches after the first match is found. That way it prints at most one file name.
 
Old 05-18-2011, 12:03 PM   #5
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
Code:
if [ "$(find -option1 -option2)" '!=' '' ]
    # find found something
else
    # no matching files found
fi
 
Old 05-18-2011, 02:38 PM   #6
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,775

Rep: Reputation: 481Reputation: 481Reputation: 481Reputation: 481Reputation: 481
case is more efficient than [ or test when you can get by with simple pattern matches.
Code:
case `find . -name 'filename' -print -quit` in
  '') echo 'No filename found' ;;
  *) echo 'Found filename' ;;
esac
 
Old 05-18-2011, 03:34 PM   #7
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by gnashley View Post
case is more efficient than [ or test when you can get by with simple pattern matches.
Hey, gnashley, thanks for the heads up: I didn't know that. In fact, I was sceptical enough to test:
Code:
time bash -c 'for F in `seq 1 10000` ; do true ; done'
time bash -c 'for F in `seq 1 10000` ; do true ; case "$F" in 50) echo 1 ; esac ; done'
time bash -c 'for F in `seq 1 10000` ; do true ; [ "$F" == "50" ] && echo 1 ; done'
time bash -c 'for F in `seq 1 10000` ; do true ; if [ "$F" == "50" ]; then echo 1 ; fi ; done'
on an Atom N270 laptop and Bash 4.1.5, the real times were 0.285s, 0.490s, 0.733s and 0.745s, respectively; meaning that ten thousand cases took +0.20s, [s +0.45s, and ifs +0.46s real time. In other words, cases took less than half the time compared to [s or ifs. Funny! But I wonder how on earth did you come across that info?
 
Old 05-18-2011, 03:42 PM   #8
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714Reputation: 714
Quote:
Originally Posted by Nominal Animal View Post
I wonder how on earth did you come across that info?
It's faster to do globbing (which is part of the shell) than it is to launch the test command.
 
Old 05-18-2011, 05:40 PM   #9
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by MTK358 View Post
It's faster to do globbing (which is part of the shell) than it is to launch the test command.
Obviously. The funny bit is that Bash does not execute test or [ for these tests, it does them internally, just like the globbing. You can verify it yourself by straceing a bash test:
Code:
strace -f -F bash -c '[ -e somefile ] && echo "somefile exists" || echo "somefile does not exist"'
Bash will only exec the external binary if you explicitly tell it to, for example by specifying the full path:
Code:
strace -f -F bash -c '/usr/bin/[ -e somefile ] && echo "somefile exists" || echo "somefile does not exist"'
 
Old 05-19-2011, 03:14 AM   #10
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,775

Rep: Reputation: 481Reputation: 481Reputation: 481Reputation: 481Reputation: 481
Sure, `type test` or `type [` will tell you that the internals are being used. I discovered that case was faster when I tried to optimize some really slow code where I was using brackets in multi-choice if-elif-then pattern comparisons. In my routine 'case' ran in about 30% of the time as using brackets. In the OP's example, the difference would probably less.
 
Old 05-19-2011, 04:21 AM   #11
Chirel
Member
 
Registered: Nov 2009
Posts: 55

Rep: Reputation: 19
Hi,

Fun to see where a simple question can bring a post

I must admit that the Nominal Animal find . -name 'filename' -print -quit is really nice.
No subcall to grep et no full tree traversal if the file is found in the begining . . . Good one.
 
Old 05-19-2011, 07:16 AM   #12
catalint
LQ Newbie
 
Registered: May 2011
Posts: 7

Original Poster
Rep: Reputation: 0
Hei you gurus ,
my issue is that on solaris -quite doesn't work. any workaround for this?

thx
 
Old 05-19-2011, 07:52 AM   #13
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943Reputation: 943
Quote:
Originally Posted by catalint View Post
my issue is that on solaris -quite doesn't work. any workaround for this?
Oh, right, -quit isn't supported by all finds. Fortunately, I have a pretty devious workaround you can use instead:
Code:
FILE=`find . -name 'filename' -print -exec sh -c 'kill -TERM $PPID' ';'`
case "$FILE" in
    '') ;;
    *)  echo "Found '$FILE'." ;;
esac
Whenever the find command finds a file, it will print the file name, then exec an sh subshell that will send a TERM signal to its parent, terminating the find command. Although that will also result in exit status 143 ("killed by TERM" in Linux and Solaris at least), the most reliable way is still to check if FILE is non-empty.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Display True file size using ls -l command in CentOS dmchenry Linux - Newbie 3 04-20-2011 08:47 AM
egrep to find a command not found string romainp Linux - General 1 09-07-2007 04:30 PM
Bash command/script to return group of file IHateFriction Programming 3 03-09-2007 01:31 PM
Return true or false if I have ping reply Menestrel Programming 4 11-29-2004 01:40 AM
why does if [ ${var:0:2}='AA' ] always return true blish_blash Programming 1 12-31-2003 09:51 AM


All times are GMT -5. The time now is 07:22 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration