0

I'm trying to put together a find command to list directories under /home with names that start with adm_ but I need the find to be case insensitive (rhel v7). Is there a way to do this?

3 Answers 3

1

The -iname option is what you are looking for.

find /home -iname 'adm_*'

Add -type d to limit to directories.

find /home -iname 'adm_*' -type d

2
  • Thanks for this, I used: cd /home; find * -maxdepth 0 -type d -iname 'adm*'
    – Vonnie
    Dec 6, 2019 at 9:40
  • 1
    find * isn't a good usage since "*" will be interpreted by bash and replaced by every non-hidden file in your home directory... so if the directory you're looking for is into an hidden directory (ie: .config) you won't see it. The path isn't mandatory so find -maxdepth 0 -typed d -iname "adm*" would be enought
    – binarym
    Dec 6, 2019 at 10:07
1

You can do this in two ways depending on what you want to do with the names that match the pattern.

If you just want to print them, use -iname rather than -name with find on your Linux system:

find /home -type d -iname 'adm_*'

To use them for something with find:

find /home -type d -iname 'adm_*' -exec sh -c '
    for dirpath do
        # use "$dirpath" here
    done' sh {} +

This would apply the in-line shell script to all directories matching the pattern case insensitively anywhere in or under /home.

If you want to restrict the search to only /home (not recursively), also insert -maxdepth 1 after the search path (before any action).

You also have the option to glob them directly in the shell. Assuming you are using bash, just set the nocaseglob shell option:

shopt -s nocaseglob
printf '%s\n' /home/adm_*/

This would print out all the pathnames of directories in /home matching the pattern case insensitively. The trailing / makes sure that we only ever match directories.

To also search inside subdirectories, additionally set the globstar option and use **:

shopt -s nocaseglob globstar
printf '%s\n' /home/**/adm_*/

You may obviously use this directly in a loop:

shopt -s nocaseglob globstar dotglob nullglob
for dirpath in /home/**/adm_*/; do
    # use "$dirpath" here
done

The dotglob option makes globbing patterns match hidden names (just like find would do), and nullglob makes sure that the pattern is removed completely if there is no match.

0

With find implementations that don't support the non-standard -iname extension, you can use:

find /home -name '[aA][dD][mM]_*' -type d

With some find implementations including GNU find as found on RHEL, that will not include files whose name contains sequences of bytes that don't form valid characters in the current locale. Doing:

LC_ALL=C find /home -name '[aA][dD][mM]_*' -type d

Would address that as in the C locale, all single byte values form one valid character each. (and a, A, d, D, m, M, _ are all part of the portable charset so generally their encoding is invariant among all locales on the system).

For the standard equivalent of GNU's -maxdepth 1 you'd do:

LC_ALL=C find /home/. ! -name . -prune -name '[aA][dD][mM]_*' -type d

(technically, that's more like -mindepth 1 -maxdepth 1 or FreeBSD's -depth 1 -prune which is in fact closer to what you need (here depth 0 (.) which you don't want is otherwise only excluded because it doesn't match that pattern)).

Not the answer you're looking for? Browse other questions tagged .