views:

442

answers:

5

Is there a shell equivalent of PHP's preg_match?

I'm trying to extract the database name from this string in a shell script.

define('DB_NAME', 'somedb');

Using preg_match in PHP I could just do something like this.

preg_match('define(\'DB_NAME\','(.*)'\'\)',$matches);
echo $matches[1];

How can I accomplish the same thing in a shell script?

+1  A: 

How about:

$ str="define('DB_NAME', 'somedb');"
$ php -r "$str echo DB_NAME;"
somedb
too much php
Thanks for the creative solution
andrew
+1  A: 
$ t="define('DB_NAME', 'somedb');"
$ echo $t
define('DB_NAME', 'somedb');
$ eval "result=(${t##*,}"
$ echo $result
somedb
$

That one does contain a bashism, and while it will work in most out-of-the-box environments, to stick with posix shell features, do the clunkier version:

t="define('DB_NAME', 'somedb');"
r="${t##*,}"
r="${r%);*}"
r=`eval echo $r`
DigitalRoss
Thanks for the quick response. Stackoverflow is amazing.Any chance you would be willing to explain how eval "result=(${t##*,}" works?
andrew
you are playing with the fact the substition come back with '); at the end this is nice but kind of not scalabale a lot (ie: easy to modify) but nice....
Chmouel Boudjnah
${t##*,} deletes the prefix string up through ",", see sh(1) or bash(1). This leaves 'somedb'); to deal with, so I added result=( in front with an eval, which got rid of the quotes and took advantage of the fact that bash lets you do assignments with =(...). CB is kinda right, but he missed the worst part of this expression: I think it's a bashism, and wouldn't work in a posix shell.
DigitalRoss
Definitely want to give CB credit for figuring it out, though :-)
DigitalRoss
In your posix version, you can eliminate using `eval` if you replace the two lines before it with `r="${t##*@(,|, )\'}"` and `r="${r%\')*}"` - note that this also handles the case where there's no space after the comma.
Dennis Williamson
A: 

something like this :

MATCHED=$(sed -n "s/^define('DB_NAME', '\(.*\)')/\1/p" file.php)

if [[ -n ${MATCHED} ]];then
  echo $MATCHED
else
  echo "No match found"
fi
Chmouel Boudjnah
+1  A: 

This might do what you want

sed -e "/DB_NAME/ s/define('DB_NAME', '\(.*\)');/\1/" /path/to/file/to/search.txt
Brenton Alker
A: 

just use the case/esac construct

mystring="define('DB_NAME', 'somedb');"
case $mystring in
    *define*DB_NAME*) 
      dbname=${mystring%\'*}
      dbname=${dname##*\'}
      echo "$dbname" ;;
esac
ghostdog74
Thanks for the answer. This code doesn't do quite what I'm trying to. I'm trying to extract the value from the string.
andrew
then just do your string manipulation to get dbname inside the case/esac structure....nothing too difficult...
ghostdog74