490

I tried the following code to replace QQ with ZZ, but it doesn't do what I want:

var1=QQ
sed -i 's/$var1/ZZ/g' $file

However, this code does what I want:

sed -i 's/QQ/ZZ/g' $file

How do I use variables in sed?

2

3 Answers 3

644

The shell is responsible for expanding variables. When you use single quotes for strings, its contents will be treated literally, so sed now tries to replace every occurrence of the literal $var1 by ZZ.

Using double quotes

Use double quotes to make the shell expand variables while preserving whitespace:

sed -i "s/$var1/ZZ/g" "$file"

When you require the quote character in the replacement string, you have to precede it with a backslash which will be interpreted by the shell. In the following example, the string quote me will be replaced by "quote me" (the character & is interpreted by sed):

sed -i "s/quote me/\"&\"/" "$file"

Using single quotes

If you've a lot shell meta-characters, consider using single quotes for the pattern, and double quotes for the variable:

sed -i 's,'"$pattern"',Say hurrah to &: \0/,' "$file"

Notice how I use s,pattern,replacement, instead of s/pattern/replacement/, I did it to avoid interference with the / in \0/.

Example

The shell then runs the above command sed with the next arguments (assuming pattern=bert and file=text.txt):

-i
s,bert,Say hurrah to &: \0/,
text.txt

If file.txt contains bert, the output will be:

Say hurrah to bert: \0/
10
  • 2
    How would one pass the "/g" option using this comma separated form?
    – blong
    Apr 1, 2014 at 13:55
  • 7
    @b.long It's a g option, so you would pass s,foo,bar,g instead.
    – Lekensteyn
    Apr 1, 2014 at 14:32
  • 1
    your single quote example isparticularly useful, covers sed using regex pattern pretty nicely! Sep 9, 2016 at 1:08
  • 7
    Or, for the uber-paranoid (like myself), sed 's/'"${foo}"'/replacement/'
    – leetbacoon
    Oct 4, 2019 at 3:01
  • 1
    @leetbacoon Your paranoia saved me a hell lot of work. I couldn't use the above patterns for my task-specific reasons.
    – betelgeuse
    Dec 1, 2020 at 7:33
206

We can use variables in sed using double quotes:

sed -i "s/$var/r_str/g" file_name

If you have a slash / in the variable then use different separator, like below:

sed -i "s|$var|r_str|g" file_name
6
  • 34
    If you have a slash / in the variable => This saved me ! My variable is a url and it contains /. Switching to use | as separator fixed my issue
    – sonlexqt
    Sep 20, 2018 at 4:39
  • 10
    Thumb up for "if you have a slash in the variable"
    – Tiina
    Apr 25, 2019 at 2:07
  • 1
    @sonlexqt, related: stackoverflow.com/questions/9366816/… Mar 19, 2020 at 6:33
  • 2
    Mannnn... I had a forward slash in my var and was pulling my hair on that.. this was a life saver... Thanks a ton.
    – Ajay Kumar
    Jan 6, 2021 at 23:57
  • 1
    The "|" was gold. Thanks! Sep 13, 2021 at 14:56
1

To expand (pun intended) on @mani's answer,

  • this solution will work for regular expressions fed to other commands, such as perl
  • use double quotes around the regex (yes, even under Unixy systems) in order to expand the variable as expected
  • | may appear in your variable's value as well, so don't be scared to try other delimiters

Not the answer you're looking for? Browse other questions tagged or ask your own question.