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 $replace
zamiast 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 $replace
zamiast 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.
set
również nie jest konieczne (a jak zamierzałeś go wykorzystać?). Po prostu replace=987654321
.
export
aby upewnić się, że zmienne są ustawione dla dzieci, ale, jak mówisz, równie łatwo możesz tego uniknąć. Jednak użycie lub nie export
jest tutaj nieistotne (kwestia stylu) i nie ma wpływu na rzeczywistą odpowiedź, czyli sposób użycia zmiennych w sed
poleceniu.
-i
opcją. Wiedziałbyś dlaczego? lub jak to działa?
$
lub `
w sed
skrypcie 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/sh
w 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)
$replace
znakó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 $replace
zawiera sed
znaki specjalne ( #
, \
). Możesz jednak wstępnie $replace
je 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"