Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

check substring in ksh

6,820 views
Skip to first unread message

Bart De Meester

unread,
Nov 9, 2001, 3:49:03 PM11/9/01
to
Hello,

I want to test if a certain string contains a substring.
I'm using ksh on solaris 2.6.
I try the following :
if [ "123test" == *test ]; then echo match; fi

This doesn't work however.
I've already tried different styles of quoting '*test', "*test",....

Who can help me?

Thanks in advance for your replies!

Best regards,

Bart

j...@spamproof.address

unread,
Nov 9, 2001, 4:03:27 PM11/9/01
to
"Bart De Meester" <bart.de...@pandora.be> writes:

> I want to test if a certain string contains a substring.
> I'm using ksh on solaris 2.6.
> I try the following :
> if [ "123test" == *test ]; then echo match; fi

It's often most convenient to do substring matches using a case block.

test=abc123test
case $test in
*123test) echo found it ;;
*) echo did not find it ;;
esac

Chris F.A. Johnson

unread,
Nov 9, 2001, 4:45:33 PM11/9/01
to
On Fri, 9 Nov 2001, Bart De Meester wrote:

> Hello,
>
> I want to test if a certain string contains a substring.
> I'm using ksh on solaris 2.6.
> I try the following :
> if [ "123test" == *test ]; then echo match; fi
>
> This doesn't work however.
> I've already tried different styles of quoting '*test', "*test",....

if [[ "123test" == *test ]]; then echo match; fi

--
Chris F.A. Johnson http://cfaj.freeshell.org
===================================================================
My code (if any) in this post is copyright 2001, Chris F.A. Johnson
and may be copied under the terms of the GNU General Public License

Bart De Meester

unread,
Nov 9, 2001, 4:54:47 PM11/9/01
to
> if [[ "123test" == *test ]]; then echo match; fi

Great !!! Thsi works.... But why?
Has someone a logical explanation for this?

Best regards,

Bart


Chris F.A. Johnson

unread,
Nov 9, 2001, 5:04:26 PM11/9/01
to
On Fri, 9 Nov 2001, Bart De Meester wrote:

> > if [[ "123test" == *test ]]; then echo match; fi
>
> Great !!! Thsi works.... But why?
> Has someone a logical explanation for this?

Because [[ is not the same as [.
Read the man page.

bill hunter

unread,
Nov 9, 2001, 5:52:41 PM11/9/01
to
On Fri, 9 Nov 2001, Bart De Meester wrote:

try this (ksh on solaris also)

#!/bin/ksh
if [[ "${1}" == *test* ]]; then
print "test string"
else
print "not test string"
fi
exit 0


--
Bill Hunter <4...@sun.com>

perl -e 'print $i=pack(c5,33*2,sqrt(5456),unpack(c,H)+4,oct(114),10)'


Heiner Steven

unread,
Nov 10, 2001, 6:23:18 AM11/10/01
to
"Chris F.A. Johnson" wrote:

> On Fri, 9 Nov 2001, Bart De Meester wrote:
>
> > > if [[ "123test" == *test ]]; then echo match; fi
> >
> > Great !!! Thsi works.... But why?
> > Has someone a logical explanation for this?
>
> Because [[ is not the same as [.
> Read the man page.

Chris, you seem to be in a hurry today ;-)

"[" is the old version of the "test" command. It has
some well-known disadvantages (e.g. quoting). The
command used to be an external one (/usr/bin/[), instead
of being a built into the shell. It was chosen not to change it,
because the changes would break existing scripts.

Instead, the KSH implementors decided to create a new command,
"[[" with extended features. This command always is directly
implemented by the shell, and therefore has less quoting
problems.

The pattern matching feature your script depends on only
work with the new version of the test command.

Heiner
--
___ _
/ __| |_ _____ _____ _ _ Heiner STEVEN <heiner...@nexgo.de>
\__ \ _/ -_) V / -_) ' \ Shell Script Programmers: visit
|___/\__\___|\_/\___|_||_| http://www.shelldorado.com/

Chris F.A. Johnson

unread,
Nov 10, 2001, 7:43:02 AM11/10/01
to
On Sat, 10 Nov 2001, Heiner Steven wrote:

> "Chris F.A. Johnson" wrote:
>
> > On Fri, 9 Nov 2001, Bart De Meester wrote:
> >
> > > > if [[ "123test" == *test ]]; then echo match; fi
> > >
> > > Great !!! Thsi works.... But why?
> > > Has someone a logical explanation for this?
> >
> > Because [[ is not the same as [.
> > Read the man page.
>
> Chris, you seem to be in a hurry today ;-)

Lack of sleep, perhaps.

> "[" is the old version of the "test" command. It has
> some well-known disadvantages (e.g. quoting). The
> command used to be an external one (/usr/bin/[), instead
> of being a built into the shell. It was chosen not to change it,
> because the changes would break existing scripts.
>
> Instead, the KSH implementors decided to create a new command,
> "[[" with extended features. This command always is directly
> implemented by the shell, and therefore has less quoting
> problems.
>
> The pattern matching feature your script depends on only
> work with the new version of the test command.

Except that [[ is not just a new version of 'test'. It is a new command,
and it adds new functionality, e.g. pattern matching.

The OP's desired behaviour is accomplished with [[, not [ or 'test'.
Which is what I said, isn't it? :)

Stephane CHAZELAS

unread,
Nov 11, 2001, 4:44:21 AM11/11/01
to
On Sat, 10 Nov 2001 12:43:02 GMT, Chris F.A. Johnson wrote:
[...]

> Except that [[ is not just a new version of 'test'. It is a new command,
> and it adds new functionality, e.g. pattern matching.
[...]

Be careful to the words you use. '[[' shouldn't be called a "command",
but rather a keyword. Parsing inside [[ ... ]] is not done the same way
as for an ordinary command line. You could think of it as a kind of
quote.

For example

op='&&'

[[ a = b $op b = c ]]
is an error, whereas

op=-a
[ a = b $op b = c ]
if not.

in
[[ ab = a* ]]
a* won't be expanded to the list of files whose name start with "a".

a="a b"
[[ $a = "a b" ]]
won't lead to an error (unlike with [ or test), there's no word
splitting inside [[ ... ]].

... etc.

But a [[ ... ]] has an exit status such as a command.

Note it's the same thing for (( ... )).

--
Stéphane

Chris F.A. Johnson

unread,
Nov 11, 2001, 6:50:42 AM11/11/01
to
On 11 Nov 2001, Stephane CHAZELAS wrote:

> On Sat, 10 Nov 2001 12:43:02 GMT, Chris F.A. Johnson wrote:
> [...]
> > Except that [[ is not just a new version of 'test'. It is a new command,
> > and it adds new functionality, e.g. pattern matching.
> [...]
>
> Be careful to the words you use. '[[' shouldn't be called a "command",
> but rather a keyword. Parsing inside [[ ... ]] is not done the same way
> as for an ordinary command line. You could think of it as a kind of
> quote.

According the the ksh93 manual:

A command is either a simple-command or one of the following.
Unless otherwise stated, the value returned by a command is that
of the last simple-command executed in the command.

[snip]
((expression))
.....
[snip]

[[ expression ]]
Evaluates expression and returns a zero exit status when
expression is true. See Conditional Expressions below, for
a description of expression.

> For example
>
> op='&&'
>
> [[ a = b $op b = c ]]
> is an error, whereas
>
> op=-a
> [ a = b $op b = c ]
> if not.
>
> in
> [[ ab = a* ]]
> a* won't be expanded to the list of files whose name start with "a".
>
> a="a b"
> [[ $a = "a b" ]]
> won't lead to an error (unlike with [ or test), there's no word
> splitting inside [[ ... ]].
>
> ... etc.
>
> But a [[ ... ]] has an exit status such as a command.
>
> Note it's the same thing for (( ... )).

Things are different in bash for some of those examples, and I haven't
tried a POSIX sh.

Stephane CHAZELAS

unread,
Nov 11, 2001, 1:40:49 PM11/11/01
to
On Sun, 11 Nov 2001 11:50:42 GMT, Chris F.A. Johnson wrote:
> On 11 Nov 2001, Stephane CHAZELAS wrote:
>
> > On Sat, 10 Nov 2001 12:43:02 GMT, Chris F.A. Johnson wrote:
> > [...]
> > > Except that [[ is not just a new version of 'test'. It is a new command,
> > > and it adds new functionality, e.g. pattern matching.
> > [...]
> >
> > Be careful to the words you use. '[[' shouldn't be called a "command",
> > but rather a keyword. Parsing inside [[ ... ]] is not done the same way
> > as for an ordinary command line. You could think of it as a kind of
> > quote.
>
> According the the ksh93 manual:
>
> A command is either a simple-command or one of the following.
> Unless otherwise stated, the value returned by a command is that
> of the last simple-command executed in the command.
>
> [snip]
> ((expression))
> .....
> [snip]
>
> [[ expression ]]
> Evaluates expression and returns a zero exit status when
> expression is true. See Conditional Expressions below, for
> a description of expression.

Yes, I only meant that '[[' shouldn't be thought of as a command
(contrary to '[').

But "[[ ... ]]" (the whole) may be considered as a command in the sense
it can appear anywhere a command is expected, and has everything of a
command behavior.

but in [[ a = b ]], you can't say that the '[[' command is run with 4
arguments (a, =, b, ]]). You can only say that " a = b " has been
evaluated as a shell condition.

Whereas (even if '[' is often a builtin command),
[ a = b ] is parsed the same way as 'command a = b ]'.
You can even redefine the '[' command:

'[' () {
printf %s "testing [ $*..."
'/bin/[' "$@"
# or bash -c '[ "$@"' bash "$@"
r=$?
case $r in
0) echo " => true";;
*) echo " => false";;
esac
return $r
}
[ a = b ]
testing [ a = b ]... => false

You can do the same with "let", you can't do the same with '[[' or '(('

> > For example
> >
> > op='&&'
> >
> > [[ a = b $op b = c ]]
> > is an error, whereas
> >
> > op=-a
> > [ a = b $op b = c ]
> > if not.
> >
> > in
> > [[ ab = a* ]]
> > a* won't be expanded to the list of files whose name start with "a".
> >
> > a="a b"
> > [[ $a = "a b" ]]
> > won't lead to an error (unlike with [ or test), there's no word
> > splitting inside [[ ... ]].
> >
> > ... etc.
> >
> > But a [[ ... ]] has an exit status such as a command.
> >
> > Note it's the same thing for (( ... )).
>
> Things are different in bash for some of those examples, and I haven't
> tried a POSIX sh.

? What do you mean?

--
Stéphane

Greg Hansen

unread,
Nov 14, 2001, 4:52:59 PM11/14/01
to
In ksh, you can do substring pattern matching with ${variable%pattern}
and ${variable#pattern} constructs:

Ex:
string="123test"
if [ ${string%"test"} != $string ]; then
echo "Substring found"
fi

0 new messages