2013-06-16 13 views
12

Jak mówi tytuł, szukam sposobu na usunięcie zdefiniowanego wzorca zarówno na początku zmiennej, jak i na końcu. Wiem, że muszę używać # i %, ale nie znam prawidłowej składni.Usuń wzór dopasowania podłańcucha zarówno na początku, jak i na końcu zmiennej

W tym przypadku, chcę usunąć http:// na początku i na końcu /score/ zmiennej $line który jest odczytywany z file.txt.

+0

Jaki wzór? Czy możesz być trochę bardziej konkretny? –

+0

tak, w tym przypadku: http: // na początku i/score/na końcu. Linia $ jest odczytywana z pliku.txt – bobylapointe

+0

To, czego szukasz, to rozszerzenie parametrów, w szczególności do twojego przypadku: '$ {słowo_parametru}' i '$ {parametr% słowo}' pod koniec [tej sekcji Bash manual] (http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) – doubleDown

Odpowiedz

17

Cóż, nie można zagnieździć ${var%}/${var#} operacji, więc będziesz musiał użyć zmiennej tymczasowej.

jak tutaj:

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

Alternatywnie, można użyć wyrażeń regularnych z (na przykład) sed:

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

Jestem bardziej znany z wyrażeń regularnych.To jest interesujące. Wiem trochę sed. Pytanie brzmi, w jaki sposób wykorzystać dane wyjściowe produkowane przez sed, aby użyć go w innym poleceniu. Powiedzmy, aby uruchomić skrypt. ./script.sh $ modifiedlemodifiedbysed – bobylapointe

+2

Zaktualizowano odpowiedź, aby pokazać, że wyjście sed może być przechowywane w zmiennej, do ponownego użycia. –

+0

To w końcu działa jak czar. Spędziłem dwie godziny na zastanawianiu się nad tym. Jestem pewien, że inni też pracują, ale znowu, lubię używać wyrażeń regularnych. Dzięki ! – bobylapointe

2

Trzeba to zrobić w 2 etapach:

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

W moim przypadku ciąg znaków może, ale nie musi zaczynać się od "boo" lub "foo" i jeśli zaczyna się od któregokolwiek z nich, jak mogę zaimplementować OR do parsowania, aby usunąć "boo" LUB "foo" od początku łańcucha? – 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

istnieje sposób, aby zrobić jeden krok używając tylko zbudowany -w funkcji bash (brak uruchomionych programów zewnętrznych, takich jak sed) - z BASH_REMATCH:

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

Dopasowuje się do wyrażenia regularnego po prawej stronie testu =~ i umieszcza grupy w tablicy BASH_REMATCH.


Powiedział, że jest to bardziej konwencjonalne użycie dwóch wyrażeń PE i tymczasową zmienną:

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

... W powyższym przykładzie, opcja extglob służy do umożliwienia powłoka uznane " extglobs "- rozszerzenia bash do składni globu (tworzenie wzorców w stylu globalnym podobnych do potęgi do wyrażeń regularnych), wśród których ?(foo) oznacza, że ​​foo jest opcjonalne.


Nawiasem mówiąc, używam printf zamiast echo w tych przykładach, ponieważ wiele z zachowań echo „s są zdefiniowane realizacja - na przykład, rozważmy przypadek, w którym zawartość zmiennej są -e lub -n.

0

jak o

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