1

I am writing a script that checks a certain directory for any sub-directories starting with a specific word.

Here is my script thus far:

#!/bin/bash

function checkDirectory() {
    themeDirectory="/usr/share/themes"
    iconDirectory="/usr/share/icons"
    # I don't know what to put for the regex. 
    regex=

    if [ -d "$themeDirectory/$regex" && -d "$iconDirectory/$regex" ]; then
       echo "Directories exist."
    else
       echo "Directories don't exist."
    fi
}

So, how would you use regex to check if a particular directory has any folders starting with a specific word?

4
  • regular expressions are more powerful than "starting with a specific word". Is there a reason you need regex?
    – Jeff Schaller
    Jun 9, 2016 at 11:13
  • @JeffSchaller I don't know, I just thought since I know the directory will have directories starting with a specific word, I thought that would be the best solution. For example, in the theme directory, I know 'Numix' is the starting word to each of the sub-directories (that is if the 'Numix' theme is installed) located inside the theme directory, thus I thought if I use regex I could locate all those files inside that directory and check if they exist or not. Jun 9, 2016 at 11:16
  • I'm a bit confused about the test expression you've written, since you seem to be checking if directories with the given name prefix exist in both of your target directories
    – ilkkachu
    Jun 9, 2016 at 11:16
  • Related: programmers.stackexchange.com/q/223634
    – Dubu
    Jun 9, 2016 at 15:34

3 Answers 3

2

-d doesn't accept regexes, it accepts filenames. If you just want to check a simple prefix, a wildcard is enough:

exists=0
shopt -s nullglob
for file in "$themeDirectory"/word* "$iconDirectory"/* ; do
    if [[ -d $file ]] ; then
        exists=1
        break
    fi
done
if ((exists)) ; then
    echo Directory exists.
else
    echo "Directories don't exist."
fi

nullglob makes the wildcards expand to empty lists if there are no matches. In a larger script, change its value in a subshell, or set back the old value once you don't need it.

2
  • So if I also wanted to check if $iconDirectory has any sub directories, I would do "$iconDirectory"/word*? Jun 9, 2016 at 11:01
  • @NicholasAdamou: It's already there.
    – choroba
    Jun 9, 2016 at 11:04
1

If you only want to find directories matching a given pattern/prefix, I think you could just use find:

find /target/directory -type d -name "prefix*"

or, if you only want immediate subdirectories:

find /target/directory -maxdepth 1 -type d -name "prefix*"

Of course, there's also -regexif you need an actual regex match. (caveat: I can't remember if -maxdepth is a gnu-ism.)

(update) Right, you wanted an if statement. Find always returns a zero, so we can't use the return value to check if anything was found (unlike with grep). But we can e.g. count the lines. Pipe the output through wc to get the count, then see if it's not zero:

if [ $(find /target/directory -type d -name "prefix*" | wc -l ) != "0" ] ; then
    echo something was found
else
    echo nope, didn't find anything
fi
4
  • So if I wanted to check this using an if-else structure, just surround the find /target/directory -type d -name "prefix*" in an if statement like: if [ find /target/directory -type d -name "prefix*" ]; then ... else .... fi? Jun 9, 2016 at 11:25
  • @NicholasAdamou, yah, I updated the answer with one way to do that (of course there are others)
    – ilkkachu
    Jun 9, 2016 at 11:58
  • 1
    -maxdepth and -regex are gnu-isms but are now found in some other find implementations (with variations for -regex). Here, you probably want -mindepth 1 -maxdepth 1 or with FreeBSD find: -depth 1. Or POSIXly find dir/. ! -name . -prune ... Jun 9, 2016 at 15:01
  • 1
    I'd do if find /target/directory -type d -name "prefix*" | grep -q '^'; then... to stop as soon as possible (or use -print -quit with GNU/FreeBSD...). Jun 9, 2016 at 15:06
1

The name of your variable regex will not be well chosen but consider setting the value to "$1" like regex="$1". Next step is to change the if statement from:

if [ -d "$themeDirectory/$regex" && -d "$iconDirectory/$regex" ]; then

to

if [ -d "$themeDirectory/$regex" ] && [ -d "$iconDirectory/$regex" ]; then

The script will become:

function checkDirectory() {
    themeDirectory="/usr/share/themes"
    iconDirectory="/usr/share/icons"
    # I don't know what to put for the regex. 
    regex="$1"

    if [ -d "$themeDirectory/$regex" ] && [ -d "$iconDirectory/$regex" ]; then
       echo "Directories exist."
    else
       echo "Directories don't exist."
    fi
}

From a shell you can source your script by:

. /path/to/script

And the function is ready for use:

checkDirectory test
Directories don't exist.
2
  • Will this locate any directories inside both the theme directory and the icon directory starting with a specific word? Jun 9, 2016 at 11:19
  • Well, 'locate' is a big word, the if statement will check if a directory (test in my sample) exist in $themeDirectory as well as in $iconDirectory. If both directories (/usr/share/themes/test and /usr/share/icons/test) exists the message "Directories exist." is printed, otherwise the message "Directories don't exist." is printed.
    – Lambert
    Jun 9, 2016 at 11:25

You must log in to answer this question.

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