How can I find a file whose name includes a given string, such as “abcde”?

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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

Use find:

find path-to-search -name '*abcde*'

Method 3

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=("[email protected]"); 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. "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2d096d">[email protected]</a>")
# writing the $-args to an array like this (using quotes) solves 
#   any possible problem with embedded whitespace 
a=("<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="85a1c5">[email protected]</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 "|"    |
#

Method 4

locate abcde | egrep "(dirA|dirB|dirC)"

for the set of directories dirA, dirB, dirC.

Or 3 find-commands.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x