Computing.Net > Forums > Unix > 'find' syntax

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

'find' syntax

Reply to Message Icon

Name: WilliamRobertson
Date: February 21, 2003 at 05:18:45 Pacific
OS: Mac OS 10.1
CPU/Ram: 400/384
Comment:

Where I'm working they have a script that uses e.g:

find $SOMEPATH/*.dat -mtime +42 -print

In all the documentation I've read, the first argument should be a search path and filenames should be specified with -name 'pattern'. I said it was wrong and wouldn't work, but it turns out it does (HP-UX) so I look like an idiot. I then tried it at home on my Mac and it works there too (FreeBSD). Am I missing something?



Sponsored Link
Ads by Google

Response Number 1
Name: James Boothe
Date: February 21, 2003 at 06:58:48 Pacific
Reply:

The first argument is actually pathname_list which can be multiple pathnames, such as:

find /tmp /u01/home ...

I think a lot of people (including me) think of pathname as only a directory. But in fact, it is a full-path reference to EITHER a directory or a file. Therefore, pathname_list can be directories, files, or a mixture of files and directories.

And of course, the shell is expanding that fileset before the find command ever sees it. So,

find myfile* -print

actually gets processed as:

find myfile1 myfile2 myfile3 -print

That fileset expansion could get very long and exceed a shell processing limit. If that happens, you can tell them they need to change it to:

find directory-list -name "*.dat" -mtime +42 -print

because the "*.dat" will not be expanded by the shell, but instead passed to the find command as is, where it will be used by find as a pattern match.

and THEN you will get the respect you deserve! :-))


0

Response Number 2
Name: WilliamRobertson
Date: February 21, 2003 at 08:41:08 Pacific
Reply:

Did you find 'pathname' defined anywhere? The man pages are a bit light on exactly what that means.

If I have files xx, yy and zz (and assuming no subdirectories):

find . -name '??' -print
# gives xx, yy, zz as expected

find ??
# expands to 'find xx yy zz'
# returns xx, yy, zz as we now know to expect

find aa
# fails with error 'find: cannot stat aa'. When I tested
# the original script I got this error, which led me to
# think the syntax was invalid.

find '??'
# fails as above because there is no file named literally ??

find xx -name yy
# can never succeed - unless xx is a directory
# and yy exists somewhere under it...

A few years ago I was working somewhere with a particularly useless DBA who would enter commands like
find . -name *.sql -print
No matter how many times we explained it to him he never understood why that sometimes worked (no files matching '*.sql' in the directory he was in), sometimes gave 'missing conjunction' (more than one file, thus giving a syntax error when expanded) and sometimes failed to find a file that was actually there (one file matching '*.sql' in current directory - took some thinking about at first).


0

Response Number 3
Name: James Boothe
Date: February 21, 2003 at 12:42:42 Pacific
Reply:

Yep, very good. I don't have a formal definition of pathname. I would say it is any full reference (root-anchored) name for any type of file or directory.

Just curious - why would find command fail to find a single *.sql file?


0

Response Number 4
Name: WilliamRobertson
Date: February 22, 2003 at 03:33:42 Pacific
Reply:

$ mkdir testdir

$ touch testdir/aa.dat testdir/bb.dat testdir/cc.dat

$ find testdir -name a*.dat -print
# Shell can't expand a*.dat, so find goes looking
# for a*.dat
# and finds one matching file:

testdir/aa.dat

$ touch az.dat

# Repeat same find command:
$ find testdir -name a*.dat -print

# a*.dat expands to 'az.dat': find goes looking for az.dat
# and finds nothing.

Also on the subject of this new (to me) syntax:

$ find aa.dat
# Not equivalent to "find . -name aa.dat":
# finds nothing.


0

Response Number 5
Name: James Boothe
Date: February 22, 2003 at 07:13:18 Pacific
Reply:

Yes, good examples. It is not the fault of the find command that:

find testdir -name a*.dat -print

does not find anything in the testdir subdirectory when a*.dat is expanded to az.dat.

The shell has been given, by default, permission to expand those patterns. Thus, as you point out, the shell changes it to

find testdir -name az.dat -print

before the find command ever executes. And as you pointed out earlier, if a*.dat were to expand into multiple filenames, this would result in "find: missing conjunction".

While it is valid syntax for pathname_list to expand into multiple entries, it is not valid for a -name pattern to do so. Therefore, the user needs to either protect these patterns from expanding by enclosing in double-quotes, or tell the shell not to do filename expansion.

The shell can be invoked with the -f option

sh -f

or by dynamically changing the noglob option. To see current shell options:

echo $-

Turn off noglob:

set -f
echo $-

Now, the command

find testdir -name a*.dat -print

will find testdir/aa.dat because a*.dat was not expanded into az.dat.

And regarding your last paragraph:

find aa.dat

finds nothing because the only pathname it was told to look at was aa.dat. It does not see aa.dat, so it finds nothing. The find command searches only the pathnames listed. It will not automatically process all files and directories in the current directory.

find testdir

will process that one pathname only. If it is a file, then it "finds" that one file. If it is a directory, it finds all files lying on that path.

find . -name aa.dat

Above command specifies the current directory as the pathname to process, so it processes all files and directories in the directory, so it will find any aa.dat files in the current directory or in any subdirectories.


0

Related Posts

See More



Response Number 6
Name: WilliamRobertson
Date: February 24, 2003 at 09:35:38 Pacific
Reply:

Yes, quite agree about shell wildcard expansion not being find's problem. I would always put wildcard expressions within a -name pattern in quotes. Just thought it made an interesting illustration of some of the perils.

I still think it's not immediately obvious from the documentation that

find aa.dat

is equivalent to something like

find . -path ./aa.dat

(except that an invalid path is an error condition, while no files found is not). I suppose it does make some sort of sense once you know.


0

Sponsored Link
Ads by Google
Reply to Message Icon






Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Unix Forum Home


Sponsored links

Ads by Google


Results for: 'find' syntax

find: [-H | -L] path-list predicate www.computing.net/answers/unix/find-h-l-pathlist-predicate/7983.html

exclude dire with find command www.computing.net/answers/unix/exclude-dire-with-find-command-/8079.html

Syntax problem with find cmd in scr www.computing.net/answers/unix/syntax-problem-with-find-cmd-in-scr/8174.html