2013-06-16 9 views
12

Come dice il titolo, sto cercando un modo per rimuovere uno schema definito sia all'inizio di una variabile che alla fine. So che devo usare # e % ma non conosco la sintassi corretta.Rimuovi il pattern di corrispondenza della sottostringa sia all'inizio che alla fine della variabile

In questo caso, voglio rimuovere http:// all'inizio, e /score/ alla fine della variabile $line che viene letto da file.txt.

+0

Che tipo di modello? Puoi essere un po 'più specifico? –

+0

sì, in questo caso: http: // all'inizio e/punteggio/alla fine. La riga $ viene letta da un file.txt – bobylapointe

+0

Quello che stai cercando è l'espansione dei parametri, in particolare nel tuo caso il '$ {parametro # parola}' e '$ {parametro% parola}' vicino alla fine di [questa sezione di Manuale di Bash] (http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) – doubleDown

risposta

17

Beh, non si può nido ${var%}/${var#} operazioni, in modo da dovrete usare variabile temporanea.

Come qui:

var="http://whatever/score/" 
temp_var="${var#http://}" 
echo "${temp_var%/score/}" 

In alternativa, è possibile utilizzare le espressioni regolari con (per esempio) sed:

some_variable="$(echo "$var" | sed -e 's#^http://##; s#/score/$##')" 
+0

Ho molta più familiarità con le espressioni regolari.Questo è interessante. Conosco un po '. La domanda è, come usare l'output prodotto da sed per usarlo in un altro comando. Diciamo di iniziare una sceneggiatura. ./script.sh $ variablemodifiedbysed – bobylapointe

+2

Aggiornamento della risposta per mostrare che l'output di sed può essere memorizzato in variabile, per il riutilizzo. –

+0

Finalmente funziona come un fascino. Ho passato due ore a capirlo. Sono sicuro che anche gli altri funzionino, ma ancora una volta mi piace usare le espressioni regolari. Grazie uomo ! – bobylapointe

2

Devi farlo in 2 fasi:

$ string="fooSTUFFfoo" 
$ string="${string%foo}" 
$ string="${string#foo}" 
$ echo "$string" 
STUFF 
+0

Nel mio caso, la stringa può o non può iniziare con 'boo' o 'foo' e se inizia con qualcuno di loro come potrei implementare un OR nell'analisi per rimuovere "boo" OR "foo" dall'inizio di una stringa? – Nazar

2
$ var='https://www.google.com/keep/score' 
$ var=${var#*//} #removes stuff upto // from begining 
$ var=${var%/*} #removes stuff from/all the way to end 
$ echo $var 
www.google.com/keep 
2

c'è un modo per farlo un passo utilizzando built solo -in base alla funzionalità (nessun programma esterno in esecuzione come sed) - con BASH_REMATCH:

url=http://whatever/score/ 
re='https?://(.*)/score/' 
[[ $url =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}" 

Corrisponde all'espressione regolare sul lato destro del test =~ e inserisce i gruppi nell'array BASH_REMATCH.


Ciò premesso, è più convenzionale utilizzare due espressioni di PE e una variabile temporanea:

shopt -s extglob 
url=http://whatever/score/ 
val=${url#http?(s)://}; val=${val%/score/} 
printf '%s\n' "$val" 

... nell'esempio precedente, l'opzione extglob viene utilizzata per consentire il guscio di riconosciuto " extglobs "- estensioni di bash alla sintassi glob (creando pattern glob-style simili in potenza alle espressioni regolari), tra cui ?(foo) significa che foo è facoltativo.


A proposito, sto usando printf piuttosto che echo in questi esempi, perché molti dei comportamenti echo s' sono definiti dall'implementazione - per esempio, si consideri il caso in cui il contenuto della variabile sono -e o -n.

0

come su

export x='https://www.google.com/keep/score'; 
var=$(perl -e 'if ($ENV{x} =~ /(https:\/\/)(.+)(\/score)/) { print qq($2);}') 
Problemi correlati