How can I search a file by its name and partial path?

71

11

Often I have a file name and it's partial path, e.g. "content/docs/file.xml".

Is there a simple way to search for that file, without manually cutting into parts its name to provide directory name and file name separately?

It'd be great if find worked in that way, so I could run find content/docs/file.xml, but unfortunately it doesn't.

user69817

Posted 2012-03-13T08:42:06.523

Reputation:

1You could try adding a * wildcard at the beginning. find -path *content/docs/file.xml worked for me. – Bob – 2012-03-13T08:58:01.153

thanks, @Bob, it's really worked for me. Btw, interesting, that if I'm adding a slash after an asterisk: "find -path */content/docs/file.xml", it doesn't work. Thanks a lot anyway. – None – 2012-03-13T09:06:48.023

also, @Bob, please make it as an answer and I'll mark it as a correct. – None – 2012-03-13T09:08:55.180

The reason the slash after asterisk didn't work is probably because the asterisk should have been escaped, see the edit to my answer. – Bob – 2012-03-13T10:55:46.390

Answers

82

Pass in a * wildcard to indicate a match for anything. You also need to escape the *s, e.g.:

find . -path \*content/docs/file.xml

or enclose the pattern in quotes, e.g.:

find . -path "*content/docs/file.xml"

As the man page describes it:

$ find . -name *.c -print

find: paths must precede expression

This happens because *.c has been expanded by the shell resulting in find actually receiving a command line like this:

find . -name bigram.c code.c frcode.c locate.c -print

That command is of course not going to work. Instead of doing things this way, you should enclose the pattern in quotes or escape the wild‐ card:

$ find . -name \*.c -print

Bob

Posted 2012-03-13T08:42:06.523

Reputation: 51 526

11

find has a -path (or the equivalent but less portable -wholename) option too find $top_dir -wholename *string*

find /usr -path *in/abiw*

>/usr/bin/abiword

technosaurus

Posted 2012-03-13T08:42:06.523

Reputation: 996

I don't know the full path, only partial, so "-wholename" won't work. – None – 2012-03-13T09:02:14.813

the flag is misleading, see my example... it just lets you extend the string into a directory if you know it – technosaurus – 2012-03-13T09:38:55.687

3

find . -type f | grep "content/docs/file.xml"

or just

locate content/docs/file.xml

Nifle

Posted 2012-03-13T08:42:06.523

Reputation: 31 337

2@user69817 - on the contrary, locate doesn't search the disk, it interrogates a locate database, which typically gets populated via cron once a day. – tink – 2018-08-09T21:12:57.923

locate is an interesting option, but it searches the whole disk, I'd like to have an ability to specify the base search directory or at least to specify using param, that search should be made from this directory (like your first option does), not from the root. – None – 2012-03-13T08:56:21.640

1

For example searching files in a location using asterisk/wildcard (*) as: dir=“/apps/*/instance01/" you could use find ${dir} -name “*.jks”. putting all the files in an array like this:

arr=(`find ${dir} -name “*.jks"`)

if you want to get files with other extensions use ‘or’ like this:

-name "*.keystore" -o -name "*.jks" -o -name “*.p12" because -name only accepts single string so use ‘or’.

Finally put everything in array like this:

arr=(`find ${dir} -name "*.keystore" -o -name "*.jks" -o -name "*.p12"`)

if you have full paths not the partial paths its much easier to put them in arrays like this:

arr=(“/Users/ajay/Documents/keystore_and_p12files/"*.{keystore,p12,jks})

user450631

Posted 2012-03-13T08:42:06.523

Reputation: 17