Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Within a set of directories, how do I find a file whose name includes a given string, such as "abcde"?

share|improve this question
add comment

4 Answers 4

up vote 13 down vote accepted

find will look through a directory structure and return results based on a glob:

find /your/dir -name "*abcde*"

Adding the -type f switch will refine your search criteria to only return files.

find /your/dir -type f -name "*abcde*"

You could also include other switches like -maxdepth 2 to restrict the search to 2 levels of directories bellow the specified one.

In this way you can build up a rich, highly targetted search command that will quickly return exactly what you need.

man find has a wealth of detail, including actions like -exec to run a command on the files returned by find and options to use regular expressions.

share|improve this answer
2  
You might also want to add -type f to the find so that you only get results that are files. find /your/dir -type f -name "*abcde*" –  Steven Pritchard Aug 1 '11 at 12:46
    
Good point Steven: I'll update my answer. Thank you. –  jasonwryan Aug 1 '11 at 18:30
add comment

If locate suits you (it is fast, but only as good as the most recent run of sudo updatedb). You can run locate using its own built-in regex facility...

Here is a parameter driven script to do what you want. Call it with $1 as the "abcde" you are looking for and with subsequent parameters as the directories:

#!/bin/bash
a=("$@"); r=''
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
locate --regex  "(${r:1}).*/[^/]*${a[0]}[^/]*$"

An example call looks like this:

$ ./script_name 'z' "$HOME/bin/perl" "$HOME/type/stuff"

As suggested by jasonwryan, here is a commented version of the script.
Bear in mind that locate always outputs fully-qualified paths.

#!/bin/bash

# Note: Do not use a trailing / for directory names
# 
# Any of the args can be an extended regex pattern. 
#
# Create an array `a` which contains "$1", "$2", "$3", etc... (ie. "$@")
# writing the $-args to an array like this (using quotes) solves 
#   any possible problem with embedded whitespace 
a=("$@")
#
# Set up an empty string which is to be built into a regex pattern 
#   of all directroy names (or an appropriate regex pattern)
r=''
#
# Each regex pattern is to be an extended regex    
# Each regex pattern is concatenated to the preceding one 
#   with the  extended-regex 'or' operator |
#
# Step through the array, starting at index 1 (ie, $2),
#   and build the 'regex-pattern' for the directories 
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
#
# Run 'locate' with
#                           |the target file pattern $1  | 
#                |zero-to-| |preceded and followed by    |
#                |-many   | |zero-to-many non-slash chars|
#                |anything| |               |‾‾‾‾‾‾‾‾‾‾‾‾
#                 ‾‾‾‾‾‾‾|| |               |   
locate --regex  "(${r:1}).*/[^/]*${a[0]}[^/]*$"
#        ________|      |  | 
#       |directory-regex| last
#       | in brackets ()| slash      
#       |stripped of its|
#       |leading "|"    |
#
share|improve this answer
    
Upvoted for the script: but it would be helpful to (extensively) comment it so it is clear as to what is actually going on in there... –  jasonwryan Aug 1 '11 at 4:34
    
Nice job, fred! I'd upvote again if I could. Thank you. –  jasonwryan Aug 1 '11 at 8:37
add comment
locate abcde | egrep "(dirA|dirB|dirC)" 

for the set of directories dirA, dirB, dirC.

Or 3 find-commands.

share|improve this answer
add comment

Use find:

find path-to-search -name '*abcde*'
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.