2009-09-15 7 views
6

Existe-t-il un équivalent shell de preg_match de PHP? J'essaie d'extraire le nom de la base de données de cette chaîne dans un script shell. En utilisant preg_match en PHP, je pourrais juste faire quelque chose comme ça.Shell équivalent de php preg_match?

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

Comment puis-je accomplir la même chose dans un script shell?

Répondre

2
$ t="define('DB_NAME', 'somedb');" 
$ echo $t 
define('DB_NAME', 'somedb'); 
$ eval "result=(${t##*,}" 
$ echo $result 
somedb 
$ 

Que l'on ne contient un bash, et tout cela fonctionnera dans la plupart des environnements hors-the-box, pour coller avec les fonctions du shell POSIX, procédez clunkier Version:

t="define('DB_NAME', 'somedb');" 
r="${t##*,}" 
r="${r%);*}" 
r=`eval echo $r` 
+1

Merci pour la réponse rapide. Stackoverflow est incroyable. Une chance que vous seriez prêt à expliquer comment eval "result = ($ {t ## *,}" fonctionne? –

+1

vous jouez avec le fait que le substition revient avec '); à la fin c'est sympa mais pas scalabale beaucoup (c'est-à-dire facile à modifier) ​​mais sympa .... –

+0

$ {t ## *,} supprime la chaîne de préfixe jusqu'à ",", voir sh (1) ou bash (1). Cela laisse 'somedb'); pour traiter, j'ai donc ajouté result = (en face d'un eval, qui s'est débarrassé des guillemets et a profité du fait que bash vous permet de faire des affectations avec = (...) CB est un peu juste, mais il a manqué la pire partie de cette expression: je pense que c'est un bashisme, et ne fonctionnerait pas dans un shell posix – DigitalRoss

2

Que diriez-vous:

$ str="define('DB_NAME', 'somedb');" 
$ php -r "$str echo DB_NAME;" 
somedb 
+0

Merci pour la solution créative –

0

quelque chose comme ceci:

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

if [[ -n ${MATCHED} ]];then 
    echo $MATCHED 
else 
    echo "No match found" 
fi 
1

Cela pourrait faire ce que vous voulez

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

il suffit d'utiliser le cas/ESAC construire

mystring="define('DB_NAME', 'somedb');" 
case $mystring in 
    *define*DB_NAME*) 
     dbname=${mystring%\'*} 
     dbname=${dname##*\'} 
     echo "$dbname" ;; 
esac 
+0

Merci pour la réponse. Ce code ne fait pas exactement ce que j'essaie de faire. J'essaie d'extraire la valeur de la chaîne. –

+0

alors faites juste votre manipulation de chaîne pour obtenir dbname dans la structure case/esac .... rien de trop difficile ... – ghostdog74

2

Utilisation des réponses expr exactement à la question:

expr match "string" "regexp" 

Alors, pour votre besoin , vous pouvez écrire:

expr match "$mystring" "define('DB_NAME', '\([^']\+\)');" 

Notez la paire \(\). Sans ces caractères, expr renverra le nombre de caractères correspondants. Avec eux, seule la partie correspondante est renvoyée. Je ne sais pas dans quels environnements expr est disponible (et a ce comportement), cependant.

+0

Ceci répond mieux au titre de la question, bien que la réponse acceptée apporte une solution complète au corps de la question , malgré ne pas répondre à la question du titre. Il est intéressant de noter que 'expr' affiche le nombre de caractères appariés et sort avec un code approprié à son résultat, qui peut être utilisé directement dans un test. Cependant, dans ce cas, la sortie doit être redirigée vers/dev/null si vous ne voulez pas que le script crache le nombre de correspondances tout le temps. – spikyjt

+0

Ce comportement peut dépendre de la version utilisée; mais sous la bash d'ubuntu, la sortie de l'expression expr dépend de la présence de paires \ (\) dans le motif. S'il n'y en a pas, alors vous avez raison, il affiche le nombre de caractères correspondants. S'il y en a, seule la partie correspondante entre les valeurs \ (\) est renvoyée. –

+0

Édité ma réponse pour inclure cette remarque –