[comp.unix.shell] string comparisons

acmfiu@serss0.fiu.edu (ACMFIU) (03/13/91)

under csh or sh, how do i compare two strings?

albert

jik@athena.mit.edu (Jonathan I. Kamens) (03/14/91)

In article <2847@kluge.fiu.edu>, acmfiu@serss0.fiu.edu (ACMFIU) writes:
|> under csh or sh, how do i compare two strings?

  Could you be more specific?  What kind of comparisons do you want to do?

  Csh supports simple string-equal comparisons, as well as pattern-matching. 
The "test" or "[" command in sh can be used to do basic comparisons of
strings, and "expr" and be used to do regular expression comparisons.

  Of course, you can use "test" and "expr" in csh too, but if you don't need
the regular expression capabilities of "expr", you're better off sticking to
the csh built-ins for speed.

  See the various man pages for more information, or post more specific
questions here.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

itkin@mrspoc.Transact.COM (Steven M. List) (03/15/91)

acmfiu@serss0.fiu.edu (ACMFIU) writes:

>under csh or sh, how do i compare two strings?

Either use expr(1) or awk(1).  Depends on how elaborate you want to get.
-- 
 +----------------------------------------------------------------------------+
 :                Steven List @ Transact Software, Inc. :^>~                  :
 :           Chairman, Unify User Group of Northern California                :
 :                         itkin@Transact.COM                                 :

wcs) (03/17/91)

In article <1991Mar14.225901.3973@mrspoc.Transact.COM> steven@Transact.COM writes:
]acmfiu@serss0.fiu.edu (ACMFIU) writes:
]
]>under csh or sh, how do i compare two strings?
]
]Either use expr(1) or awk(1).  Depends on how elaborate you want to get.

The test program (aka "[") is accessible from either shell, and is a
builtin for modern shells like ksh.  In sh, just do
	if [ "$foo" = "$bar" ]
	then true-stuff
	else false-stuff
Read the manual for csh.
-- 
				Pray for peace;
					Bill
# Bill Stewart 908-949-0705 erebus.att.com!wcs AT&T Bell Labs 4M-312 Holmdel NJ
# Hacker.  System Designer.  Troublemaker.

alex@am.sublink.org (Alex Martelli) (03/19/91)

wcs@cbnewsh.att.com (Bill Stewart 908-949-0705 erebus.att.com!wcs) writes:
:In article <1991Mar14.225901.3973@mrspoc.Transact.COM> steven@Transact.COM writes:
:]acmfiu@serss0.fiu.edu (ACMFIU) writes:
:]>under csh or sh, how do i compare two strings?
:]Either use expr(1) or awk(1).  Depends on how elaborate you want to get.
:The test program (aka "[") is accessible from either shell, and is a
:builtin for modern shells like ksh.  In sh, just do
:    if [ "$foo" = "$bar" ]
:    then true-stuff
:    else false-stuff

I believe that the following approach should be often faster:

case $foo in
    "$bar")    true-stuff ;;
    *)        false-stuff ;;
esac

since "case", and the "globbing-like" behavior of its pattern-matching,
IS guaranteed to be builtin to sh.  NOT earth-shattering differences,
mind you!, but given these two scripts on my 386/20, Interactive 2.2:
---cut: pep
#!/bin/sh
fai='abe*cou'
ogu='abe*cou'
for i in 0 1 2 3 4 5 6 7 8 9
do
	case $fai in
		"$ogu")	echo "$fai" si! ;;
		*)		echo "$fai" no! ;;
	esac >/dev/null 
done
fai='abetocou'
for i in 0 1 2 3 4 5 6 7 8 9
do
	case $fai in
		"$ogu")	echo "$fai" si! ;;
		*)		echo "$fai" no! ;;
	esac >/dev/null 
done
---cut: pap
#!/bin/sh
fai='abe*cou'
ogu='abe*cou'
for i in 0 1 2 3 4 5 6 7 8 9
do
	if [ $fai = $ogu ]
		then	echo "$fai" si! ;
		else	echo "$fai" no! ;
	fi >/dev/null 
done
fai='abetocou'
for i in 0 1 2 3 4 5 6 7 8 9
do
	if [ $fai = $ogu ]
		then	echo "$fai" si! ;
		else	echo "$fai" no! ;
	fi >/dev/null 
done
---end cut

/bin/time says, for pap:
real        1.6
user        0.3
sys         1.2

while for pep:
real        0.5
user        0.0
sys         0.4

with very repeatable measurements (+-0.1 second max on each number
over quite a few repetitions), so the case would appear to be 2 to 3
times faster than the if [ ] (despite the "dilution" of the for,
echos to /dev/null, and other trinkets in common between the two
scripts).

Besides, the globbing in the case statement turns out handy quite
often... (sometimes it's a bother instead - see the above quotes around
"$ogu").

I learned Unix on underpowered/overloaded machines, so my istincts
push me to "optimize" even such trifles.  I realize that "if [ ]"
will look more readable/understandable/maintainable than "case" to
most people, and no doubt it may even be faster in shells with test
built-in... so please don't flame on these accounts!  I'm just trying
to suggest an alternative technique that may avoid some extra forks
in more "traditional" sh's.

-- 
Alex Martelli - (home snailmail:) v. Barontini 27, 40138 Bologna, ITALIA
Email: (work:) martelli@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only), Fidonet: 332/401.3 (home only).