2009-09-15 16 views
6

Czy istnieje odpowiednik powłoki preg_match PHP?Powłoki równoważne php preg_match?

Próbuję wyodrębnić nazwę bazy danych z tego ciągu w skrypcie powłoki.

Używając preg_match w PHP mogłem po prostu zrobić coś takiego.

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

Jak mogę zrobić to samo w skrypcie powłoki?

Odpowiedz

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

Że jeden nie zawierają bashowymi, a jednocześnie będzie działać w większości out-of-the-box środowiskach, aby trzymać się z funkcjami powłoki POSIX, wykonaj clunkier wersja:

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

Dzięki za szybką odpowiedź. Stackoverflow jest niesamowity. Czy masz szansę wyjaśnić, jak działa eval "result = ($ {t ## *,}"? –

+1

grasz z tym, że podstawienie wraca z '); na końcu jest to miłe, ale nie dość skalabale (tzn. łatwe do modyfikacji), ale ładne ... –

+0

$ {t ## *,} usuwa ciąg prefiksu przez ",", patrz sh (1) lub bash (1). To pozostawia "somedb"); radzić sobie z tym, więc dodałem wynik = (z przodu z evalem, który pozbył się cytatów i wykorzystał fakt, że bash pozwala ci wykonywać przydziały z = (...). CB ma rację, ale przeoczył najgorsza część tego wyrażenia: myślę, że to bashizm, i nie działałby w powłoce posix.) – DigitalRoss

2

Jak o:

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

Dzięki za kreatywne rozwiązanie –

0

coś takiego:

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

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

To może robić co chcesz

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

wystarczy użyć sprawę/ESAC skonstruować

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

Dzięki za odpowiedź. Ten kod nie spełnia dokładnie tego, co próbuję. Próbuję wyodrębnić wartość z ciągu. –

+0

to po prostu zrób manipulację ciągiem, aby uzyskać nazwę dbn wewnątrz struktury case/esac ... nic nie jest zbyt trudne ... – ghostdog74

2

Korzystając z wyr odpowiedzi dokładnie na pytanie:

expr match "string" "regexp" 

Tak, dla potrzeb , możesz napisać:

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

Zwróć uwagę na parę \(\). Bez tych znaków wyrażenie zwróci liczbę zgodnych znaków. Przy ich użyciu zwracana jest tylko odpowiednia część.

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

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

Nie wiem, w których środowiskach expr jest dostępny (i ma takie zachowanie).

+0

To najlepiej odpowiada tytułowi pytania, chociaż zaakceptowana odpowiedź stanowi kompletne rozwiązanie dla treści pytania , pomimo braku odpowiedzi na tytułowe pytanie. Warto zauważyć, że 'wyr' wypisuje liczbę dopasowanych znaków i wyjść z kodem odpowiednim do wyniku, który można wykorzystać bezpośrednio w teście. Jednak w takim przypadku wynik powinien zostać przekierowany do/dev/null, jeśli nie chcesz, aby skrypt wypluwał cały czas liczbę dopasowań. – spikyjt

+0

To zachowanie może zależeć od używanej wersji; ale pod bash ubuntu, wynik dopasowania expr zależy od tego, czy istnieją pary \ (\) we wzorze. Jeśli nie ma, to masz rację, wyprowadza liczbę dopasowanych znaków. Jeśli tak, zwracana jest tylko część dopasowana między \ (\). –

+0

Zmieniono moją odpowiedź, aby uwzględnić tę uwagę –