2013-06-16 42 views
12

Wie der Titel sagt, suche ich nach einer Möglichkeit, ein definiertes Muster sowohl am Anfang einer Variablen als auch am Ende zu entfernen. Ich weiß, dass ich # und % verwenden muss, aber ich kenne nicht die korrekte Syntax.Entfernen übereinstimmende Teilstringmuster am Anfang und am Ende der Variablen

In diesem Fall mag ich http:// am Anfang zu entfernen, und /score/ am Ende der Variablen $line, die von file.txt gelesen wird.

+0

Welche Art von Muster? Kannst du etwas genauer sein? –

+0

Ja, in diesem Fall: http: // am Anfang und/score/am Ende. Die $ -Zeile wird aus einer file.txt gelesen. – bobylapointe

+0

Was Sie suchen, ist die Parametererweiterung, speziell für Ihren Fall die '$ {Parameter # Wort}' und '$ {Parameter% Wort}' am Ende von [dieser Abschnitt von Bash Handbuch] (http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) – doubleDown

Antwort

17

Nun, Sie können nicht verschachtelt ${var%}/${var#} Operationen, so dass Sie temporäre Variable verwendet werden müssen.

wie hier:

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

Alternativ können Sie reguläre Ausdrücke mit (zum Beispiel) verwenden sed:

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

Ich bin mit regulären Ausdrücken viel vertrauter.Das ist interessant. Ich weiß sed ein bisschen. Die Frage ist, wie man die von sed erzeugte Ausgabe benutzt, um sie in einem anderen Befehl zu verwenden. Lassen Sie uns ein Skript starten. ./script.sh $ variablemodifiedbysed – bobylapointe

+2

Die Antwort wurde aktualisiert, um anzuzeigen, dass die Ausgabe von sed zur Wiederverwendung in einer Variablen gespeichert werden kann. –

+0

Das funktioniert endlich wie ein Zauber. Ich habe zwei Stunden damit verbracht, das herauszufinden. Ich bin mir sicher, dass die anderen auch funktionieren, aber ich benutze wieder gerne reguläre Ausdrücke. Danke, Mann ! – bobylapointe

2

Sie haben es in 2 Schritten zu tun:

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

In meinem Fall kann die Zeichenfolge mit "boo" oder "foo" beginnen oder nicht und wenn es mit einem von ihnen beginnt, wie könnte ich ein OR in das Parsing implementieren, um "boo" ODER "foo" vom Anfang eines Strings zu entfernen? – 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

Es gibt einen Weg, ihm einen Schritt zu tun, nur gebaut unter Verwendung von -in Bash-Funktionalität (keine laufenden externen Programme wie sed) - mit BASH_REMATCH:

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

Dies stimmt mit dem regulären Ausdruck auf der rechten Seite des =~-Tests überein und fügt die Gruppen in das Array BASH_REMATCH ein.


Das heißt, es ist eher konventionellen zwei PE Ausdrücke zu verwenden und eine temporäre Variable:

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

... in dem obigen Beispiel die extglob Option wird verwendet, die Schale, damit erkannt " extglobs "- die Erweiterungen von bash auf die glob-Syntax (die glob-style-Muster haben eine ähnliche Stärke wie reguläre Ausdrücke), wobei ?(foo) bedeutet, dass foo optional ist.


By the way, ich bin mit printf anstatt echo in diesen Beispielen, weil viele von echo ‚s Verhalten Implementierung definiert sind - zum Beispiel der Fall betrachtet, in dem der Inhalt der Variable -e oder -n sind.

0

wie etwa

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