Używam poniższego kodu do zamiany ciągu znaków w skrypcie powłoki.
echo $LINE | sed -e 's/12345678/"$replace"/g'
ale jest zastępowany przez $replacezamiast wartości tej zmiennej.
Czy ktokolwiek mógłby powiedzieć, co poszło nie tak?
Używam poniższego kodu do zamiany ciągu znaków w skrypcie powłoki.
echo $LINE | sed -e 's/12345678/"$replace"/g'
ale jest zastępowany przez $replacezamiast wartości tej zmiennej.
Czy ktokolwiek mógłby powiedzieć, co poszło nie tak?
Odpowiedzi:
Jeśli chcesz interpretować $replace, nie powinieneś używać apostrofów, ponieważ uniemożliwiają one podstawianie zmiennych.
Próbować:
echo $LINE | sed -e "s/12345678/\"${replace}\"/g"
zakładając, że chcesz wstawić cudzysłowy. Jeśli nie chcesz cytatów, użyj:
echo $LINE | sed -e "s/12345678/${replace}/g"
Transkrypcja:
pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _
Uważaj tylko, aby upewnić się, że ${replace}nie ma żadnych znaczących postaci sed(jak /na przykład), ponieważ spowoduje to zamieszanie, chyba że ucieknie. Ale jeśli, jak mówisz, zamieniasz jedną liczbę na inną, nie powinno to stanowić problemu.
setrównież nie jest konieczne (a jak zamierzałeś go wykorzystać?). Po prostu replace=987654321.
exportaby upewnić się, że zmienne są ustawione dla dzieci, ale, jak mówisz, równie łatwo możesz tego uniknąć. Jednak użycie lub nie exportjest tutaj nieistotne (kwestia stylu) i nie ma wpływu na rzeczywistą odpowiedź, czyli sposób użycia zmiennych w sedpoleceniu.
-iopcją. Wiedziałbyś dlaczego? lub jak to działa?
$lub `w sedskrypcie był poprzedzony odwrotnym ukośnikiem, aby chronić go przed mechanizmem zastępowania przez powłokę ciągów w podwójnych cudzysłowach.
możesz użyć powłoki (bash / ksh).
$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc
/bin/shw wielu nowoczesnych Linuksach.
Nie jest to specyficzne dla pytania, ale dla osób, które potrzebują tego samego rodzaju funkcjonalności rozszerzonej dla jasności z poprzednich odpowiedzi:
# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
# this is just how this feature works :/
result=${str//$find/$replace}
echo $result
# result is: someFileName.bar
str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result
# result is: someFileName.sally because ".foo" was not found
Znalazłem wdzięczne rozwiązanie .
echo ${LINE//12345678/$replace}
echo $LINE | sed -e 's/12345678/'$replace'/g'
nadal możesz używać pojedynczych cudzysłowów, ale musisz je „otworzyć”, jeśli chcesz, aby zmienna została rozwinięta we właściwym miejscu. w przeciwnym razie ciąg jest traktowany „dosłownie” (jak poprawnie stwierdził @paxdiablo, jego odpowiedź jest również poprawna)
$replaceznaków poza cudzysłowami spowoduje, że powłoka wykona tokenizację białych znaków i rozwinięcie wartości z użyciem symboli wieloznacznych. Wydaje się, że działa to z prostymi wartościami, ale może dramatycznie wybuchnąć w przypadku nietrywialnych łańcuchów. Nie używaj tego w kodzie produkcyjnym.
Aby pozwolić powłoce rozwinąć zmienną, musisz użyć podwójnych cudzysłowów, takich jak
sed -i "s#12345678#$replace#g" file.txt
Spowoduje to uszkodzenie, jeśli $replacezawiera sedznaki specjalne ( #, \). Możesz jednak wstępnie $replaceje zacytować:
replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt
Miałem podobny wymóg do tego, ale mój zamiennik var zawierał znak ampersand. Ucieczka przed ampersandem rozwiązała mój problem:
replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"
Użyj tego zamiast tego
echo $LINE | sed -e 's/12345678/$replace/g'
to działa dla mnie po prostu usuń cytaty
Wolę używać podwójnych cudzysłowów, ponieważ pojedyncze znaki są bardzo potężne, ponieważ ich używaliśmy, jeśli nie jesteśmy w stanie niczego zmienić w środku lub możemy wywołać zmienne podstawienie.
więc używaj zamiast tego podwójnych cudzysłowów.
echo $LINE | sed -e "s/12345678/$replace/g"