2010-08-20 22 views
26

Ho una stringacome first url, second url, third url e vorrebbe estrarre solo il url dopo la parola second nel X Terminal sistema operativo (solo la prima occorrenza). Come posso farlo?stringa Estratto stringa utilizzando RegEx nel terminale

In il mio editor preferito ho usato l'espressione regolare /second (url)/ e utilizzati $1 per estrarlo, solo che non so come farlo nel terminale.

Tenete a mente che url è un URL reale, sarò con una di queste espressioni di abbinarlo: Regex to match URL

risposta

41
echo 'first url, second url, third url' | sed 's/.*second//' 

Edit: ho frainteso. Meglio:

echo 'first url, second url, third url' | sed 's/.*second \([^ ]*\).*/\1/' 

o:

echo 'first url, second url, third url' | perl -nle 'm/second ([^ ]*)/; print $1' 
+0

restituisce 'url, terzo url' =/ –

+0

Il terzo comando funziona meglio (non è necessario eseguire una parentesi di escape e tale = great) ma restituisce tutte le occorrenze (con il mio input, un file lungo, 13 volte ciascuna), Avrei solo bisogno del primo –

+0

Ho aggiunto un inelegante '| sed -n '1 s /./\./ p'' dopo il comando perl e tutto ha funzionato bene = D Grazie! –

8

Nell'altra risposta a patto di rimanere ancora con tutto dopo l'URL desiderato. Quindi ti propongo la seguente soluzione.

echo 'first url, second url, third url' | sed 's/.*second \(url\)*.*/\1/' 

Sotto sed si raggruppa un'espressione sfuggendo alla parentesi attorno ad esso (standard POSIX).

+0

A +1 per le informazioni sulla fuga =) –

0

Durante il tentativo, ciò che probabilmente hai dimenticato era l'argomento -E per sed.

Da sed --help:

-E, -r, --regexp-extended 
       use extended regular expressions in the script 
       (for portability use POSIX -E). 

Non è necessario cambiare in modo significativo la vostra espressione regolare, ma si ha bisogno di aggiungere .* per abbinare avidamente intorno ad esso per rimuovere l'altra parte della stringa.

Questo funziona bene per me:

echo "first url, second url, third url" | sed -E 's/.*second (url).*/\1/' 

uscita:

url 

in cui l'uscita "url" è in realtà la seconda istanza nella stringa. Ma se già sai che è formattato tra virgola e spazio, e non permetti questi caratteri negli URL, allora la regex [^,]* dovrebbe andare bene.

Opzionalmente:

echo "first http://test.url/1, second ://test.url/with spaces/2, third ftp://test.url/3" \ 
    | sed -E 's/.*second ([a-zA-Z]*:\/\/[^,]*).*/\1/' 

quali uscite in modo corretto:

://example.com/with spaces/2 
4

Tubazioni ad un altro processo (come 'sed' e 'perl' suggerito sopra) potrebbe essere molto costoso, soprattutto quando è necessario eseguire questa operazione più volte.Bash fa supporto regexp:

[[ "string" =~ regex ]]

Analogamente al modo in cui si estrae partite nel vostro editor preferito utilizzando $1, $2, ecc, Bash riempie nel $BASH_REMATCH array con tutte le partite.

Nel vostro esempio particolare:

str="first usr1, second url2, third url3" 
if [[ $str =~ (second)([^,]*) ]]; then echo "match: '${BASH_REMATCH[2]}'"; else echo "no match found"; fi 

uscita:

match: 'url2' 

In particolare, =~ supporta esteso espressioni regolari as defined by POSIX, ma con estensioni specifiche della piattaforma (che variano in estensione e può essere incompatibile).
Su piattaforme Linux (GNU userland), vedere man grep; su piattaforme macOS/BSD, vedere man re_format.