Results 1 to 6 of 6
Hi all,
I'm running on Suse Linux 9.0 Enterprise server and I'm working on several scripts to be used for various tasks.
I am not familiar with scripting and I'm ...
- 08-16-2007 #1Just Joined!
- Join Date
- Aug 2007
- Posts
- 12
String comparison in Shell scripting.
Hi all,
I'm running on Suse Linux 9.0 Enterprise server and I'm working on several scripts to be used for various tasks.
I am not familiar with scripting and I'm still quite new as a linux operator, so I'm still learning the ropes regarding what commands are available and how to use those commands.
I am currently writing a script that connects to a database, runs a query and returns that query. Those results are returned, in the form of a string, and placed into a variable.
I now need to parse that string, looking for specific words and/or expressions to test against, and based on what those results are, perform the appropriate action and return the appropriate information.
So my question to you is this:
How do I take this string "this is a test to see if you are working" and look for "test" or "working" or "this" and then perform the appropriate action for each of these words separately?
Thanks in advance.
- 08-16-2007 #2Linux Engineer
- Join Date
- Feb 2005
- Posts
- 1,044
The simplest way is with grep:
Or you could use case:Code:$VAR="this is a test to see if you are working" if echo $VAR | grep " test " >/dev/null 2>&1 then # do stuff for "test" elif echo $VAR | grep " working " >/dev/null 2>&1 then # do stuff for "working" else # do stuff for anything else fi
Code:$VAR="this is a test to see if you are working" case "$VAR" in "* test *") # do stuff for "test" ;; "* working *") # do stuff for "working" ;; *) # do stuff for anything else ;; esac
- 08-16-2007 #3Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Hi.
I like case because it is quite readable. There are some builtin pattern matching operators in bash, although they are sometimes overlooked, and probably not portable to all other Bourne-style shells. Making a correction in "$VAR=" to "VAR="and fleshing out the script:
producing:Code:#!/bin/bash # @(#) s1 Demonstrate limited ability of [[ for patterns. set -o nounset echo echo "GNU bash $BASH_VERSION" >&2 echo VAR="this is a test to see if you are working" echo " Original string = |$VAR|" echo " Checking for :test:" if [[ "$VAR" == *test* ]] then echo do stuff for "test" elif [[ "$VAR" == *working* ]] then echo do stuff for "working" else echo do stuff for anything else fi exit 0
cheers, drlCode:% ./s1 GNU bash 2.05b.0(1)-release Original string = |this is a test to see if you are working| Checking for :test: do stuff for test
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed of
the primaries described below under CONDITIONAL EXPRESSIONS.
Word splitting and pathname expansion are not performed on the
words between the [[ and ]]; tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution,
process substitution, and quote removal are performed.
When the == and != operators are used, the string to the right
of the operator is considered a pattern and matched according to
the rules described below under Pattern Matching. The return
value is 0 if the string matches or does not match the pattern [sic],
respectively, and 1 otherwise. Any part of the pattern may be
quoted to force it to be matched as a string.
-- man bashWelcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )
- 08-16-2007 #4Just Joined!
- Join Date
- Aug 2007
- Posts
- 12
Gentlemen,
Thank you very much for your responses. I very much appreciate the help. I have a couple of follow up questions for both of you to help in my understanding of the commands and what they really mean.
what exactly is this line doing and why? why are the "" needed and why are ** used around test? is this because it is considered a regular expression?Code:if [[ "$VAR" == *test* ]]
What exactly does the code at the end do? It looks like it's piping the output to a null but what's the rest of the line do?Code:echo $VAR | grep " working " >/dev/null 2>&1
thanks again guys. Much appreciated.
- 08-17-2007 #5
In the case of the first line, let's start with the quotes. This is because Bash is actually stupid. Bash expands variables exactly as they are. So for instance:
In the first case, it works fine. But in the second, where $VAR has two words, we end up with an invalid expression. Bash expects only a single statement before the '=='. This is why we use the quotes. This way, in either case, it's just a single statement. In Bash scripting, you almost always want to surround variables in quotes in order to get correct behavior.Code:VAR=word if [[ $VAR == *test* ]] => if [[ word == *test* ]] VAR=two words if [[ $VAR == *test* ]] => if [[ two words == *test* ]]
As for the *test*, it's not strictly a regular expression, but rather a shell pattern. This is much simpler than a regex (though it is similar). Shell patterns have character classes (the same as in regexes), and the special characters * and ?. * means 0 or more of any character, and ? means a single character. These do not apply to anything, rather they are placeholders. So for instance, the following all match:
and so on. So in this case, we're checking to see if $VAR contains the phrase "test" at any point (that is, "test", with 0 or more characters before or after it).Code:atest => ?test btest => ?test abctest => *test testing => test* testing => test??? .hello => [.a]hello ahello => [.a]hello
For the second block of code, this uses I/O redirection. You can read up on the details at:
http://www.tldp.org/LDP/abs/html/io-redirection.html
The nitty gritty that this line is doing:
- Redirect stdout to /dev/null (a special file that just discards anything it is given)
- Redirect stderr to wherever stdout is pointing
All programs have 3 file streams by default:
stdin (0)
stdout (1)
stderr (2)
The URL I showed you explains how to redirect all of these and the basic pattern of redirection. Also note that if you want to redirect both stdout and stderr to the same place, you can do the way shown here, or use "&> /dev/null".
Also, the greatest reference I have ever found for Bash scripting is:
http://www.tldp.org/LDP/abs/html/
Hope that all makes sense.DISTRO=Arch
Registered Linux User #388732
- 08-18-2007 #6Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Hi.
A tip o' the hat to Cabhan for his explanation of why the quotes are so important.
On a related topic, if you have bash3, and if you wanted to use regular expressions in preference to filename expressions, then you can replace the "==" operator with the "=~" operator:
producing:Code:#!/bin/bash3 # @(#) s2 Demonstrate ability of [[ and =~ for regular expressions. set -o nounset echo echo "GNU bash $BASH_VERSION" >&2 echo " MUST USE VERSION 3 FOR REGULAR EXPRESSIONS WITH =~ OPERATOR!" echo VAR="this is a test to see if you are working" echo " Original string = |$VAR|" echo " Checking for :test:" if [[ "$VAR" =~ test ]] then echo do stuff for "test" elif [[ "$VAR" =~ working ]] then echo do stuff for "working" else echo do stuff for anything else fi exit 0
See Recipe 6.8, page 122 ff, 480 ff in O'Reilly Media -- Bookstore: bash Cookbook, Albing et al. and man bash3 (or whatever it might be on your system) for details ... cheers, drlCode:% ./s2 GNU bash 3.00.16(1)-release MUST USE VERSION 3 FOR REGULAR EXPRESSIONS WITH =~ OPERATOR! Original string = |this is a test to see if you are working| Checking for :test: do stuff for test
Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )


Reply With Quote
