Question

I need to compare strings in shell:

var1="mtu eth0"

if [ "$var1" == "mtu *" ]
then
    # do something
fi

But obviously the "*" doesn't work in Shell. Is there a way to do it?

Was it helpful?

Solution

bash

Shortest fix:

if [[ "$var1" = "mtu "* ]]

Bash's [[ ]] doesn't get glob-expanded, unlike [ ] (which must, for historical reasons).


bash --posix

Oh, I posted too fast. Bourne shell, not Bash...

if [ "${var1:0:4}" == "mtu " ]

${var1:0:4} means the first four characters of $var1.


/bin/sh

Ah, sorry. Bash's POSIX emulation doesn't go far enough; a true original Bourne shell doesn't have ${var1:0:4}. You'll need something like mstrobl's solution.

if [ "$(echo "$var1" | cut -c0-4)" == "mtu " ]

OTHER TIPS

Use the Unix tools. The program cut will happily shorten a string.

if [ "$(echo $var1 | cut -c 4)" = "mtu " ];

... should do what you want.

You can call expr to match strings against regular expressions from within Bourne Shell scripts. The below seems to work:

#!/bin/sh

var1="mtu eth0"

if [ "`expr \"$var1\" : \"mtu .*\"`" != "0" ];then
  echo "match"
fi

I'd do the following:

# Removes anything but first word from "var1"
if [ "${var1%% *}" = "mtu" ] ; then ... fi

Or:

# Tries to remove the first word if it is "mtu", checks if we removed anything
if [ "${var1#mtu }" != "$var1" ] ; then ... fi

In Bourne shell, if I want to check whether a string contains another string:

if [  `echo ${String} | grep -c ${Substr} ` -eq 1 ] ; then

Enclose echo ${String} | grep -c ${Substr} with two ` backticks:

To check whether the substring is at the beginning or at the end:

if [ `echo ${String} | grep -c "^${Substr}"` -eq 1 ] ; then
...
if [ `echo ${String} | grep -c "${Substr}$"` -eq 1 ] ; then

I like to use the case statement to compare strings.

A trivial example is

case "$input"
in
  "$variable1") echo "matched the first value" 
     ;;
  "$variable2") echo "matched the second value"
     ;;
  *[a-z]*)  echo "input has letters" 
     ;;
  '')       echo "input is null!"
     ;;
   *[0-9]*)  echo "matched numbers (but I don't have letters, otherwise the letter test would have been hit first!)"
     ;;
   *) echo "Some wacky stuff in the input!"
esac

I've done crazy things like

case "$(cat file)"
in
  "$(cat other_file)")  echo "file and other_file are the same"
      ;;
  *)  echo "file and other_file are different"
esac

And that works too, with some limitations, such as the files can't be more than a couple megabytes and the shell simply doesn't see nulls, so if one file is full of nulls and the other has none, (and neither have anything else), this test won't see any difference between the two.

I don't use the file-comparing as a serious example, only an example of how the case statement is capable of doing much more flexible string matching than is available with test or expr or other similar shell expressions.

Or, as an example of the =~ operator:

if [[ "$var1" =~ "mtu *" ]]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top