1

as all know we can check easily if folder exists by the following bash command

[[ -d /opt/presto-server ]] && echo folder exist

but when we have folder as

/opt/presto-server-32.34

then how to use regular expression in order to validate that folder is exists

with this rule

presto-server-<any charecter>

as

presto-server-454.545
presto-server-4a-434
presto-server-aa-434-l

etc

Paradox
  • 1,425
yael
  • 13,106
  • you say "re" for regular expression, but you don't actually need a regex, right? Your test is "any character" -- so you don't care what those following characters are? Does there need to be a dash between presto-server and the remainder? – Jeff Schaller Apr 03 '19 at 14:53
  • yes dash is between presto-server to any character – yael Apr 03 '19 at 14:55
  • What about find with regexp ? https://stackoverflow.com/a/19840606/912046 – el-teedee Apr 03 '19 at 14:55
  • yes But I ask with bash not by find command – yael Apr 03 '19 at 14:56

3 Answers3

3

I would count how many parameters resulted from the expansion of a wildcard. First, I would set nullglob so that if there are no matches, we get the expected zero instead of the wildcard itself.

shopt -s nullglob

Then ask for the expansion of the desired pattern and set them as the current parameters:

set -- /opt/presto-server-*/

Note the addition of the trailing slash -- that requires that the resulting matches are directories (or symlinks to directories).

Then ask how many there are:

[ "$#" -gt 0 ] && echo "There are one or more presto-server- directories"
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • but if for example presto-server- , is file and not folder , then its not so good – yael Apr 03 '19 at 15:04
  • @yael, that's why I put the trailing slash on the wildcard; files won't match. – Jeff Schaller Apr 03 '19 at 15:13
  • how to return back the - shopt -s nullglob ( as was before ) – yael Apr 03 '19 at 15:25
  • Depending on your overall goal, you could use a subshell or one of these questions: https://unix.stackexchange.com/q/255338/117549 or https://unix.stackexchange.com/q/406216/117549 or https://unix.stackexchange.com/q/310957/117549 – Jeff Schaller Apr 03 '19 at 15:29
  • If you're sure that you usually have it unset, though, you could juset shopt -u nullglob at the end. – Jeff Schaller Apr 03 '19 at 15:30
  • 2
    Another way is to not use shopt at all, then do the set and test whether $1 is a directory. Would work in /bin/sh too then. – Kusalananda Apr 03 '19 at 19:31
2

You could define a function has_dirs like:

has_dirs() {
  for f do
    [ -d "$f" ] && return
  done
  false
}

And use it as:

if has_dirs /opt/presto-server-*; then
  echo there are matching dirs
fi

That's for directories or symlinks to directories. For directories only, you'd need:

    [ -d "$f" ] && [ ! -L "$f" ] && return

To more specifically match on prestor-server-<number>-<number>, with bash, you can do:

shopt -s extglob # to enable a subset of ksh extended globs
has_dirs /opt/presto-server-+([[:digit:]])-+([[:digit:]])

Though beware that it could give a false positive it there was a directory called literally /opt/presto-server-+([[:digit:]])-+([[:digit:]]) (the failglob or nullglob options can work around that).

1

If switching to zsh is an option:

if ()(($# > 0)) /opt/presto-server-*(N/); then
  echo there are directories matching that pattern
fi

Where

  • () compound-command args is an anonymous function with arguments
  • ((...)): compound command that evaluates the ... arithmetic expression and returns success if it results in a number other than 0.
  • $# > 0: arithmetic expression that evaluates to 1 if $# (the number of arguments to that anonymous function) is greater than 0.
  • (N/): glob qualifiers: N to turn on nullglob for that one glob, / to only select the files of type directory (change to -/ to also include symlinks to directories).

That's not terribly efficient as that computes the whole list of directories (for which zsh needs to do a lstat() on each matching file) which are later sorted, while finding just one directory would have been sufficient.

You can change * to <->-<-> to specifically match a sequence of numbers separated by -.

Of course, within bash, you can always do:

if zsh -c '()(($# > 0)) /opt/presto-server-<->-<->(N/)'; then
  echo there are directories matching that pattern
fi