LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Pattern matching with a "case" statement in BASH (https://www.linuxquestions.org/questions/programming-9/pattern-matching-with-a-case-statement-in-bash-439378/)

King V 04-27-2006 11:01 AM

Pattern matching with a "case" statement in BASH
 
Ok, I'm not entirely sure what I'm doing wrong here, or if it's just a limitation of the scripting language, but I'm having a bit of trouble trying to match strings in a particular circumstance.

Let's say I'm going to compare a string variable to a string that has the text "mytext", but it can have zero or more spaces preceeding it, and zero or more spaces following it, and it must still match.

that is, the following should match (braces are used just to show where the string begins and ends, and are not actually part of the string):

[mytext]
[ mytext]
[ mytext ]
[mytext ]

etc.. but there can be more than one preceeding or appending spaces.

Now, with the case statement, I've tried to use the following:

case "$thestring" in

[\ ]*mytext[\ ]*) do_something;;
*) do_nothing;;
esac


.. but there's no match when there's ZERO spaces before or after the text, only if there's at least one.

Is there any way that I'm missing that I can use to do this with a single entry in the case, or am I absolutely required to do something as follows:

case "$thestring" in

mytext) do_something;;
mytext[\ ]*) do_something;;
[\ ]*mytext) do_something;;
[\ ]*mytext[\ ]*) do_something;;
*) do_nothing;;
esac

crabboy 04-27-2006 01:29 PM

with the brackets [] you are implying that you always have at least one of the characters there, in your case, just a space.

crabboy 04-27-2006 01:31 PM

looking a bit more the * after the brackets should help you out, I'll have another look

ioerror 04-27-2006 01:51 PM

It would be easier to strip any whitespace off before you test the string. Unfortunately, bash's syntax is crap and doesn't support nested expansion, so you'll need to use a tmp variable, e.g.

Code:

tmp="${thestring# }"
thestring="${tmp% }"
case "$thestring" in
...


King V 04-27-2006 02:50 PM

I think I'd have to loop those first two lines, because they'd only take the first leading and first trailing space from the string. At that point, I'm thinking the multiple-case entries might be a touch more efficient than looping.

If there were more than one space before and/or more than one space after, it wouldn't work as-is, if I'm reading it right. :scratch:

I think I might just go with the 4-cases variant, since the asterisk after the [] doesn't seem to do what I thought it would.

On the other hand, if I knew that there'd only be zero or one spaces, then would the following work (without the use of a temporary variable):
Code:

thestring="${thestring# }"
thestring="${thestring% }"
case "$thestring" in
...


(the killer though is whether or not I can be assured of no more than one leading or trailing space)

crabboy 04-27-2006 03:09 PM

Code:

#!/bin/sh

thestring=" mytext"

newstring=`echo $thestring | sed 's/\ //g'`

case "$newstring" in


    mytext) echo something;;
    *) echo nothing;;

esac


muha 04-27-2006 03:44 PM

wouldn't ${test//\ /} do what you want? Strips all spaces.
Code:

$ ~: test="    php      jpg        "
$ ~: echo ${test//\ /}
phpjpg


King V 04-27-2006 03:47 PM

crabboy: I like that one.

Doing some time-testing, it's actually slower than checking the four-cases, but I like your method. It's more elegant-looking (ok, at least *I* think so).

EDIT: Ugh, but then I just realized something (thanks to seeing muha's example, actually) . . in the event that there's spaces in the midst of the string, it'll nuke those, too, much like muha's example. Bummer. For my needs, there *shouldn't* be spaces in the midst of the text, but again, it's one of those things where I can't absolutely be assured of that.

ioerror 04-27-2006 04:19 PM

Quote:

(the killer though is whether or not I can be assured of no more than one leading or trailing space)
Bugger, misread your original post, thought there was only 1 space. If this were my script, I'd use

Code:

${${thestring# ##}% ##}
...but that'll only work in zsh.

Bash is a piece of crap when it comes to manipulating variables, so I think crabboy's sed suggestion might be the way to go here. Just add a 's/ *$//g' to handle trailing spaces (don't forget, you need to use -e if you pass more than one expression to sed).


All times are GMT -5. The time now is 04:23 AM.