2009-09-15 29 views
6

¿Hay un equivalente de shell de preg_match de PHP?Shell equivalente de php preg_match?

Estoy tratando de extraer el nombre de la base de datos de esta cadena en un script de shell.

define('DB_NAME', 'somedb'); 

Uso de preg_match en PHP Podría hacer algo como esto.

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

¿Cómo puedo lograr lo mismo en un script de shell?

Respuesta

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

que uno no contienen una del bash, y mientras que funcionará en la mayoría de los entornos fuera de la caja, para seguir con las funciones de shell POSIX, haga lo clunkier versión:

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

Gracias por la respuesta rápida. Stackoverflow es increíble. Cualquier posibilidad de que esté dispuesto a explicar cómo funciona el resultado "eval = ($ {t ##,}"? –

+1

está jugando con el hecho de que la substición vuelve con '); al final esto es bueno, pero no scalabale mucho (es decir: fácil de modificar) pero agradable ... –

+0

$ {t ## *,} borra la cadena de prefijo hacia arriba a través de ",", ver sh (1) o bash (1). Esto deja 'somedb'); para tratar, así que agregue result = (al frente con un eval, que eliminó las comillas y aprovechó el hecho de que bash te permite hacer asignaciones con = (...). CB es un poco correcto, pero se perdió la peor parte de esta expresión: creo que es un bashismo, y que no funcionaría en un shell de posix. – DigitalRoss

2

¿Qué tal:

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

Gracias por la solución creativa –

0

algo como esto:

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

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

Esto puede hacer lo que quiera

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

sólo tiene que utilizar el caso/ESAC construir

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

Gracias por la respuesta. Este código no hace exactamente lo que intento. Estoy tratando de extraer el valor de la cadena. –

+0

luego haga su manipulación de cadenas para obtener dbname dentro de la estructura caso/esac ... nada demasiado difícil ... – ghostdog74

2

El uso de respuestas expr exactamente a la pregunta: ¿

expr match "string" "regexp" 

Por lo tanto, para su necesidad , usted puede escribir:

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

Observe el par \(\). Sin estos caracteres, expr devolverá el número de caracteres coincidentes. Con ellos, solo se devuelve la parte correspondiente.

$ string="define('DB_NAME', 'toto');" 
$ expr match "$string" "define('DB_NAME', '[^']\+');" 
26 

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

No sé bajo qué entornos expr está disponible (y tiene este comportamiento), sin embargo.

+0

Esto responde mejor al título de la pregunta, aunque la respuesta aceptada proporciona una solución completa al cuerpo de la pregunta , a pesar de no responder la pregunta del título. Vale la pena señalar que 'expr' genera el número de caracteres coincidentes y las salidas con un código apropiado para su resultado, que se puede utilizar directamente en una prueba. Sin embargo, en este caso, la salida debe redirigirse a/dev/null si no desea que el script escuche el número de coincidencias todo el tiempo. – spikyjt

+0

Este comportamiento puede depender de la versión utilizada; pero bajo el bash de ubuntu, expr match output depende de si hay \ (\) pares en el patrón. Si no hay, entonces tienes razón, muestra el número de caracteres coincidentes. Si hay, solo se devuelve la parte coincidente entre el \ (\). –

+0

Editado mi respuesta para incluir esta observación –