2009-09-15 17 views
6

Esiste un equivalente shell del preg_match di PHP?equivalente shell di php preg_match?

Sto cercando di estrarre il nome del database da questa stringa in uno script di shell.

define('DB_NAME', 'somedb'); 

Uso di preg_match in PHP Ho potuto fare qualcosa del genere.

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

Come posso ottenere lo stesso risultato in uno script di shell?

risposta

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

che uno non contengono una da bash, e mentre funzionerà nella maggior parte degli ambienti out-of-the-box, di attaccare con caratteristiche shell POSIX, eseguire le ingombranti versione:

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

Grazie per la risposta rapida. Stackoverflow è fantastico. Qualunque possibilità si sarebbe disposti a spiegare come eval "result = ($ {t ## *,}" funziona? –

+1

si sta giocando con il fatto che la sottotitoli ritorna con '); alla fine questo è bello ma non molto scalabile (es: facile da modificare) ma bello .... –

+0

$ {t ## *,} cancella la stringa del prefisso attraverso ",", vedi sh (1) o bash (1). Questo lascia 'somedb'); per affrontare, quindi ho aggiunto risultato = (di fronte a un eval, che si è sbarazzato delle virgolette e ha approfittato del fatto che bash ti permette di fare assegnamenti con = (...). CB ha ragione, ma ha perso la parte peggiore di questa espressione: penso che sia un bashismo e non funzionerebbe in una shell posix – DigitalRoss

2

ne dite:

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

Grazie per la soluzione creativa –

0

qualcosa di simile:

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

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

Questo potrebbe fare quello che vuoi

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

basta usare il caso/esac costruire

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

Grazie per la risposta. Questo codice non fa esattamente quello che sto cercando di fare. Sto cercando di estrarre il valore dalla stringa. –

+0

poi fai la tua manipolazione delle stringhe per ottenere dbname all'interno della struttura case/esac .... niente di troppo difficile ... – ghostdog74

2

L'utilizzo di risposte expr esattamente alla domanda:

expr match "string" "regexp" 

Quindi, per il vostro bisogno , puoi scrivere:

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

Annotare la coppia \(\). Senza questi caratteri, expr restituirà il numero di caratteri corrispondenti. Con loro, viene restituita solo la parte corrispondente.

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

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

Non so con quali ambienti expr è disponibile (e ha questo comportamento), però.

+0

Questo risponde meglio al titolo della domanda, sebbene la risposta accettata offra una soluzione completa al corpo della domanda , nonostante non abbia risposto alla domanda del titolo. Vale la pena notare che 'expr' restituisce il numero di caratteri corrispondenti ed esce con un codice appropriato al suo risultato, che può essere usato direttamente in un test. Tuttavia, in questo caso, l'output dovrebbe essere reindirizzato a/dev/null se non si desidera che lo script sputi fuori il numero di corrispondenze per tutto il tempo. – spikyjt

+0

Questo comportamento può dipendere dalla versione utilizzata; ma sotto la base di ubuntu, l'output della corrispondenza di expr dipende dal fatto che ci siano coppie \ (\) nel modello. Se non ci sono, allora hai ragione, emette il numero di caratteri corrispondenti. Se ci sono, viene restituita solo la parte corrispondente tra il \ (\). –

+0

Modificato la mia risposta per includere questa osservazione –