Próbowałem poniższy kod, żeby wymienić QQ
z ZZ
, ale nie robi tego, co chcę:
var1=QQ
sed -i 's/$var1/ZZ/g' $file
Jednak ten kod robi to, co chcę:
sed -i 's/QQ/ZZ/g' $file
Jak używać zmiennych w sed
?
Próbowałem poniższy kod, żeby wymienić QQ
z ZZ
, ale nie robi tego, co chcę:
var1=QQ
sed -i 's/$var1/ZZ/g' $file
Jednak ten kod robi to, co chcę:
sed -i 's/QQ/ZZ/g' $file
Jak używać zmiennych w sed
?
Odpowiedzi:
Powłoka odpowiada za rozwijanie zmiennych. Kiedy użyjesz pojedynczych cudzysłowów dla ciągów, jego zawartość będzie traktowana dosłownie, więc sed
teraz próbuje zastąpić każde wystąpienie literału $var1
przez ZZ
.
Użyj podwójnych cudzysłowów, aby powłoka rozwijała zmienne przy jednoczesnym zachowaniu białych znaków:
sed -i "s/$var1/ZZ/g" "$file"
Kiedy potrzebujesz znaku cudzysłowu w ciągu zastępującym, musisz poprzedzić go odwrotnym ukośnikiem, który zostanie zinterpretowany przez powłokę. W poniższym przykładzie ciąg quote me
zostanie zastąpiony przez "quote me"
(znak &
jest interpretowany przez sed
):
sed -i "s/quote me/\"&\"/" "$file"
Jeśli masz dużo meta-znaków powłoki, rozważ użycie pojedynczych cudzysłowów dla wzorca i podwójnych cudzysłowów dla zmiennej:
sed -i 's,'"$pattern"',Say hurrah to &: \0/,' "$file"
Zauważ, jak używam s,pattern,replacement,
zamiast s/pattern/replacement/
, zrobiłem to, aby uniknąć zakłóceń /
w \0/
.
Powłoka następnie uruchamia powyższe polecenie sed
z następnymi argumentami (przy założeniu pattern=bert
i file=text.txt
):
-i
s,bert,Say hurrah to &: \0/,
text.txt
Jeśli file.txt
zawiera bert
, wynik będzie:
Say hurrah to bert: \0/
g
opcja, więc s,foo,bar,g
zamiast tego zdasz .
\\0
zamiast tego \0
, nie należy tego robić, gdy \0
jest ujęty w pojedyncze cudzysłowy. W przeciwnym razie sed
wzór zastąpi literał \0
zamiast całego dopasowania.
Możemy używać zmiennych przy sed
użyciu podwójnych cudzysłowów:
sed -i "s/$var/r_str/g" file_name
Jeśli masz /
zmienną ukośną, użyj innego separatora, jak poniżej:
sed -i "s|$var|r_str|g" file_name
/
w zmiennej => To mnie uratowało! Moja zmienna jest adresem URL i zawiera /
. Przejście na używanie |
jako separatora naprawiło mój problem