Jeśli uruchomię te polecenia ze skryptu:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
w porządku.
Ale jeśli uruchomię:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
Czytam w tutorialach, że aby zastąpić zmienne środowiskowe z powłoki, musisz przestać i „wycenić” tę $varname
część, aby nie została ona podstawiona bezpośrednio, co zrobiłem i która działa tylko wtedy, gdy zmienna jest zdefiniowana bezpośrednio wcześniej.
Jak sprawić, by sed rozpoznał $var
zmienną środowiskową zdefiniowaną w powłoce?
set -x
w powłoce, aby powłoka echa każdego polecenia tuż przed ich wykonaniem. To może rozwiązać wiele nieporozumień. (Ponadto często używam,set -u
abyset -e
Odpowiedzi:
Dwa przykłady wyglądają identycznie, co sprawia, że problemy są trudne do zdiagnozowania. Potencjalne problemy:
Możesz potrzebować podwójnych cudzysłowów, jak w
sed 's/xxx/'"$PWD"'/'
$PWD
może zawierać ukośnik, w takim przypadku musisz znaleźć znak, który nie jest zawarty,$PWD
aby użyć go jako separatora.Być może do rozwiązania obu problemów naraz
źródło
Oprócz odpowiedzi Normana Ramseya, chciałbym dodać, że możesz podwójnie zacytować cały ciąg (co może sprawić, że instrukcja będzie bardziej czytelna i mniej podatna na błędy).
Więc jeśli chcesz wyszukać „foo” i zastąpić go zawartością $ BAR, możesz umieścić polecenie sed w cudzysłowie.
W pierwszym przypadku $ BAR nie rozwija się poprawnie, podczas gdy w drugim $ BAR rozwija się poprawnie.
źródło
"2,$s/^/$foo/"
jak$s
zostanie zinterpretowane jako zmienna zbyt i nie powinno.W podstawieniu możesz użyć innych znaków oprócz „/”:
źródło
sed
barfing z powodu interpretacji/
zawartości 2 $. Właśnie tego potrzebowałem, żeby to ominąć. Dzięki za świetną wskazówkę!Kolejna łatwa alternatywa:
Ponieważ
$PWD
zwykle będzie zawierał ukośnik/
, użyj|
zamiast/
instrukcji sed:źródło
$PWD
...?Po edycji pytania widzę twój problem. Powiedzmy, że bieżącym katalogiem jest
/home/yourname
... w tym przypadku twoje polecenie poniżej:zostanie rozwinięty do
co nie jest poprawne. Jeśli chcesz to zrobić, musisz umieścić
\
znak przed każdym/
w $ PWD.źródło
zły sposób: zmień separator
może to nie jest ostateczna odpowiedź,
nie możesz wiedzieć, w której postaci wystąpi
$PWD
,/
:
LUB@
.dobrym sposobem jest zastąpienie znaku specjalnego w
$PWD
.dobry sposób: separator ucieczki
na przykład: spróbuj zastąpić
URL
jako $ url (ma:
/
w treści)w ciągu $ tmp
za. użyj
/
jako separatoraLUB
b. użyj
:
jako separatora (bardziej czytelny niż/
)źródło
W rzeczywistości najprostszą rzeczą (przynajmniej w gnu sed) jest użycie innego separatora dla polecenia podstawienia sed. Więc zamiast s / pattern / '$ mypath' / rozwiniętego do s / pattern // my / path /, który oczywiście myli polecenie s, użyj s! Pattern! '$ Mypath'! który zostanie rozszerzony do s! pattern! / my / path! Użyłem znaku huku (!) (Lub czegokolwiek, co lubisz), co pozwala uniknąć zwykłego ukośnika do przodu jako separatora.
źródło
gdzie VAR zawiera to, co chcesz zastąpić pole
źródło
Radzenie sobie ze ZMIENNYMI w sed
źródło
Miałem podobny problem, miałem listę i muszę zbudować skrypt SQL oparty na szablonie (który zawiera
@INPUT@
jako element do zamiany):źródło