0

I have a string variable which could have values like below.

my_string=" "
my_string="   "
my_string="name1"
my_string="name 2"

I have to identify if my_string has only spaces/whitespaces and exit the program when it has only whitespaces. If it has one or two spaces inbetween, it's a valid string.

How to check if the string has only whitespaces and exit the shell script based on that.

Thank you.

Padfoot123
  • 1,057
  • 3
  • 24
  • 43
  • "Shell" meaning /bin/sh or bash? (bash has built-in support for extended regular expressions) – Charles Duffy Mar 30 '22 at 18:58
  • (also, what do you mean "between"? Between individual words in the string? Between the start and end of the string?) – Charles Duffy Mar 30 '22 at 18:59
  • ...have you tried to follow the advice given in preexisting questions like [Check if a string matches a regex in bash script](https://stackoverflow.com/questions/21112707/check-if-a-string-matches-a-regex-in-bash-script) or [Count occurances of a char in a string using bash](https://stackoverflow.com/questions/16679369/count-occurrences-of-a-char-in-a-string-using-bash)? If so, where did you get stuck? – Charles Duffy Mar 30 '22 at 19:01
  • /bin/sh. Between start and end of string – Padfoot123 Mar 30 '22 at 19:08
  • If you want to do pattern matches in `/bin/sh`, the `case` statement is your friend. It's not as powerful as a real regex engine, but if you don't want to use `grep`, it's what you have (and it's often powerful _enough_). I can't speak beyond that because I still don't understand your requirements in any detail. – Charles Duffy Mar 30 '22 at 19:21
  • Which specific cases should your program consider a successful state? We know that nothing-but-whitespace is unsuccessful. I _think_ we know that more-than-two-spaces is unsuccessful, but that's a guess/inference as it isn't explicitly stated. You aren't saying if a string with no spaces at all is successful or not. Please [edit] the question to make your requirements clear, and **also** to explain the specific technical question that needs to be resolved for you to successfully implement those requirements on your own. – Charles Duffy Mar 30 '22 at 19:23
  • See [the POSIX definition of `case`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05) re: pattern matching. For example, `case $my_string in *[![:space:]]*) :;; *) echo "No non-space characters found; exiting" >&2; exit 1;; esac` is how one would use `case` to implement one specific rule that might be relevant in this program. I haven't yet seen a specification explicitly described in this question that you _couldn't_ implement with `case`, but I'm still unclear on the details of what you're trying to accomplish. – Charles Duffy Mar 30 '22 at 19:26
  • @Padfoot123 : If it has 2 spaces between, it is valid. What if it has 3 or more spaces between start and and (`"name 2"`)? What is the expected outcome with leading/trailing spaces, i.e. `" a b "` ? – user1934428 Mar 31 '22 at 08:22

2 Answers2

2

Your question is somewhat unclear. However the following example should point you in the right direction.

#!/bin/sh

#my_string=""
my_string="     "
#my_string="   "
#my_string="name1"
#my_string="name 2"

case "$my_string" in
  "")             echo "string is empty";;
  *[![:space:]]*) echo "string does not contain only whitespace";;
  *)              echo "string contains only whitespace"; exit 1;;
esac

If you want to test only for spaces and tabs rather than all whitespace, you should use [:blank:] instead of [:space:].

fpmurphy
  • 2,464
  • 1
  • 18
  • 22
  • Nice use of case. Since your interpreter is bash, for bonus points the example could be `my_array=( "" " " " " "name1" "name 2"); for my_string in "${my_array[@]}"; do case ... done`. Not a critique, just a tip. – David C. Rankin Mar 31 '22 at 04:16
  • Good solution, but requires bash, while the OP is looking for a POSIX shell solution. – user1934428 Mar 31 '22 at 07:03
  • @user1934428 What part of the case conditional construct is non-POSIX? – fpmurphy Mar 31 '22 at 07:49
  • I thought it was the `[![:space:]]` glob pattern. Or is this already present in POSIX? – user1934428 Mar 31 '22 at 07:56
  • @user1934428. Err, glob is a pathname generator that implements the rules defined in the Shell and Utilities volume of POSIX.1-2017, Section 2.13, Pattern Matching Notation, with optional support for rule 3 in the Shell and Utilities volume of POSIX.1-2017, Section 2.13.3, Patterns Used for Filename Expansion. – fpmurphy Mar 31 '22 at 08:04
  • You are right! I found the POSIX definition [here](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05). (That page is linked from the Section 2.13.3). – user1934428 Mar 31 '22 at 08:09
0

Since you are searching for a solution in POSIX shell, I would do something like this:

if [ "$(echo $my_string | tr -d ' ')" = '' ]
then
  echo The string is blank
fi
user1934428
  • 19,864
  • 7
  • 42
  • 87
  • This is very inefficient as it requires the use of `tr` which is not a shell builtin. Your example also fails for a tab. POSIX regards a tab as whitespace! – fpmurphy Mar 31 '22 at 08:00
  • Right, I was thinking of space characters only. Even worse, I now notice that the OP said: _If it has **one or two** spaces inbetween, it's a valid string_. This makes me wonder whether `a b` is considered valid or not. – user1934428 Mar 31 '22 at 08:03